本书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 specializationPromotion<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
.
这两个专业都适用,所以我们需要确定哪个“比”另一个“更专业”,然后选择那个。如何?我们会说 X
比 Y
更专业如果它至少和Y
一样专业 ,但是 Y
至少不像X
那么专业.虽然看起来这只是在绕过问题,但我们可以使用一个聪明的规则来回答这个新问题:
X
至少和Y
一样专业如果,无论我们将什么类型分配给 X
的模板参数,结果类型总是可以匹配 Y
.
请注意,我们忘记了当前实例化中涉及的特定类型(在本例中为 double
)——“至少与”关系是部分特化本身的属性,而不是取决于特定的实例化。
专精 1 是否总能与专精 2 相匹配?这个过程有点像代数。我们要求任何类型T
,我们可以找到类型 T1
和 T2
这样:
Promotion<Array<T1>, Array<T2> > = Promotion<T, T>
这意味着:
Array<T1> = T
Array<T2> = T
所以答案是否定的。只看第一个隐含结果,给定任何类型 T
, 通常不可能找到类型 T1
这样 Array<T1>
与 T
的类型相同. (如果 T
恰好是 Array<long>
会起作用,但如果 T
是 int
或 char*
或大多数其他类型则不起作用。)
反过来呢?专精2总能和专精1匹配吗?我们要求对于任何类型 T1
和 T2
,我们可以找到一个类型 T
这样:
Promotion<T, T> = Promotion<Array<T1>, Array<T2> >
暗示:
T = Array<T1>
T = Array<T2>
所以答案再次是否定的。给定任何类型 T1
, 总是可以找到类型 T
这样 T
与 Array<T1>
的类型相同-- 直接设置 T = Array<T1>
.但一般来说其他类型T2
不限于与 T1
相同, 如果不是(例如 T1 = bool
但 T2 = float
),则将无法找到类型 T
这与 Array<T1>
相同和 Array<T2>
.所以一般来说,不可能找到这样的类型 T
.
在这种情况下,不仅两种特化都不比另一种特化,甚至特化程度也不如另一种。因此,如果需要实例化此模板类并且两个特化匹配——正如 Anon 给出的示例中所做的那样——则无法选择“最佳”类。
关于c++ - 为什么这些模板模棱两可?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4435159/