c++ - 为什么这些模板模棱两可?

标签 c++ templates

本书C++ Templates : The Complete Guide在第 275 页有一个例子,我无法理解。

书中摘录...

template <typename T>
class Promotion<T,T> {
  public:
    typdef T ResultT;
};

template<typename T1, typename T2>
class Promotion<Array<T1>, Array<T2> > {
  public:
    typedef Array<typename Promotion<T1,T2>::ResultT> ResultT;
};

template<typename T>
class Promotion<Array<T>, Array<T> > {
  public:
    typedef Array<typename Promotion<T,T>::ResultT> ResultT;
};

Unfortunately, the partial specialization Promotion<Array<T1>, Array<T2> > is neither more nor less specialized than the partial specialization Promotion<T,T>. To avoid template selection ambiguity, the last partial specialization was added. It is more specialized than either of the previous two partial specializations.

为什么前两个模板有歧义,为什么最后一个模板解决了歧义问题?当我尝试应用这些规则时,我要么无法弄清楚它是如何产生歧义的,要么我认为我有办法让它发生,但我不知道为什么最后一个模板可以解决问题。

最佳答案

也许您的困惑源于关系“比”更特化。这是一个部分顺序,而不是一个总顺序——这意味着给定 2 个模板特化,并不总是一个比另一个更专业。

Anon 的评论是正确的:假设 3rd 特化不存在,并且稍后在您的代码中有:

Promotion<Array<double>, Array<double> > foo;

(当然,您实际上可能不会创建这种空结构类型的变量,但这只是强制其实例化的最简单方法。)

鉴于 foo 的声明, 将选择前 2 个专业中的哪一个?

  • 专业 1 适用,T = Array<double> .
  • 专业 2 适用,T1 = double , T2 = double .

这两个专业都适用,所以我们需要确定哪个“比”另一个“更专业”,然后选择那个。如何?我们会说 XY 更专业如果它至少和Y一样专业 ,但是 Y至少不像X那么专业.虽然看起来这只是在绕过问题,但我们可以使用一个聪明的规则来回答这个新问题:

X至少和Y一样专业如果,无论我们将什么类型分配给 X 的模板参数,结果类型总是可以匹配 Y .

请注意,我们忘记了当前实例化中涉及的特定类型(在本例中为 double)——“至少与”关系是部分特化本身的属性,而不是取决于特定的实例化。

专精 1 是否总能与专精 2 相匹配?这个过程有点像代数。我们要求任何类型T ,我们可以找到类型 T1T2这样:

Promotion<Array<T1>, Array<T2> > = Promotion<T, T>

这意味着:

Array<T1> = T
Array<T2> = T

所以答案是否定的。只看第一个隐含结果,给定任何类型 T , 通常不可能找到类型 T1这样 Array<T1>T 的类型相同. (如果 T 恰好是 Array<long> 会起作用,但如果 Tintchar* 或大多数其他类型则不起作用。)

反过来呢?专精2总能和专精1匹配吗?我们要求对于任何类型 T1T2 ,我们可以找到一个类型 T这样:

Promotion<T, T> = Promotion<Array<T1>, Array<T2> >

暗示:

T = Array<T1>
T = Array<T2>

所以答案再次是否定的。给定任何类型 T1 , 总是可以找到类型 T这样 TArray<T1> 的类型相同-- 直接设置 T = Array<T1> .但一般来说其他类型T2不限于与 T1 相同, 如果不是(例如 T1 = boolT2 = float ),则将无法找到类型 T这与 Array<T1> 相同和 Array<T2> .所以一般来说,不可能找到这样的类型 T .

在这种情况下,不仅两种特化都不比另一种特化,甚至特化程度也不如另一种。因此,如果需要实例化此模板类并且两个特化匹配——正如 Anon 给出的示例中所做的那样——则无法选择“最佳”类。

关于c++ - 为什么这些模板模棱两可?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4435159/

相关文章:

c++ - 从模板参数继承并在 C++ 中向上转换

c++ - std::function 作为 sighandler_t

c++ - 为各种 Ubuntu 版本编译 C++

c++ - 字符串到 float 的转换?

c++ - 如何重构具有大量 std::cin 和 std::cout 操作的程序?

C++ Unresolved external lnk1120 和类模板

c++ - 使用模板类型名的指针初始化

c++ - 我们可以在指针变量中添加最多多少颗星星

比较 sizeof(type) == constant 时,C++ 模板特化不起作用

c++模板函数用const参数覆盖参数推导