c++ - 模板特化,其中模板化类型也是模板

标签 c++ templates

我已经为字符串转换创建了一个小的实用函数,这样我就不必到处创建 ostringstream 对象了

template<typename T>
inline string ToString(const T& x)
{
    std::ostringstream o;
    if (!(o << x))
        throw BadConversion(string("ToString(") + typeid(x).name() + ")");
    return o.str();
}

我想为字符串流没有默认重载 << 运算符(即 std::pair、std::set、我自己的类)的实例提供此方法的一些特化,并且我遇到了困难模板化。如果我想能够,我将用 std::pair 示例进行说明

string str = ToString(make_pair(3, 4));

我能想到的唯一方法是为 int 定义显式特化

template<>
inline string ToString(const pair<int,int>& x)
{
    std::ostringstream o;
    if (!(o << "[" << x.first << "," << x.second << "]"))
        throw BadConversion(string("ToString(pair<int,int>)"));
    return o.str();
}

有没有办法为一般情况定义它?

template<>
inline string ToString(const pair<T1,T2>& x)
{
    std::ostringstream o;
    if (!(o << "[" << x.first << "," << x.second << "]"))
        throw BadConversion(string("ToString(pair<T1,T2>)"));
    return o.str();
}   

最佳答案

不要专门化模板,而是重载它。编译器将根据函数参数类型的特化(这称为部分排序)对它们进行排序,从而找出要采用的函数模板。

template<typename T1, typename T2>
inline string ToString(const std::pair<T1, T2>& x) {
    std::ostringstream o;
    if (!(o << "[" << x.first << "," << x.second << "]"))
        throw BadConversion(string("ToString(pair<T1,T2>)"));
    return o.str();
}

一般来说,部分排序的结果将完全符合您的预期。更详细的,考虑拥有这两个功能

template<typename T> void f(T);
template<typename T, typename U> void f(pair<T, U>);

现在,为了查看一个是否至少与另一个一样专业,我们对两个函数模板进行了以下测试:

  1. 为每个模板参数选择一些独特的类型,将其替换到函数参数列表中。
  2. 将该参数列表作为参数,对另一个模板进行参数推导(使用这些参数对另一个模板进行虚拟调用)。如果推演成功,不需要转换(加const就是这样)。

上面的例子:

  1. 替换某种类型 X1进入T给我们一些类型,称之为 X1 . X1 的论证推导反对pair<T, U>不会工作。所以第一个至少不像第二个模板那样专业。
  2. 替换类型 Y1Y2进入pair<T, U>产量 pair<Y1, Y2> .对 T 进行论证推导第一个模板的作品:T将被推断为 pair<Y1, Y2> .所以第二个至少和第一个一样专业。

规则是,函数模板 A 比另一个 B 更专业,如果 A 至少与 B 一样专业,但 B 至少不与 A 一样专业。因此,在我们的示例中,第二个获胜:它是更专业,如果我们原则上可以调用两个模板函数,就会选择它。

恐怕,那个概述很匆忙,我只是针对类型参数做了它并跳过了一些细节。查看14.5.5.2在 C++ 标准规范中查看详细信息。克

关于c++ - 模板特化,其中模板化类型也是模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/947943/

相关文章:

C++ IOS 额外字符

c++ - cmake 和默认编译器

c++ - 一个容器来存储很多元素

c++ - 是否可以检测指向成员函数的指针?

C++ 继承问题,错误 LNK1120 和 LNK2019

c++ - std::map 或类似数据结构中的键压缩

c++ - 包含依赖于类成员的模板的类

c++ - 在 constexpr 函数中实例化多个模板

WPF控件模板

c++ - 安全方便的泛型散列(用于 STL 无序集和映射)成语?