gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:54:50 33 4
gpt4 key购买 nike

我已经为字符串转换创建了一个小的实用函数,这样我就不必到处创建 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/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com