在C ++ 11草案的14.8.2.4p10中,写了
如果考虑的每种类型,给定的模板至少对所有类型都是专用的,对某些类型的集合更专用,而另一种模板对于任何类型都不是更专用的,或者至少不适用于任何类型,那么给定的模板比其他模板更专业。
为什么有“或者至少不适合任何类型”?据我所知,如果我们有一个类型列表
T1, T2, T3
U1, U2, U3
如果所有Ts至少都是专业的,有些则更专业。并且没有一个人更专业,那么在我看来,从逻辑上讲,整个T的集合比U集合更专业。那么为什么当没有一个人至少比相应的Ts更专业时,会提到回退?
答案 0 :(得分:7)
更新:现已添加为official C++ Issue
我终于想出了如何阅读有问题的段落。我在下面标注了它
如果考虑的每种类型,给定模板至少对所有类型都是专用的,并且
- 更专门用于某些类型,而另一个模板对于任何类型都不是更专业,或
- {其他模板}至少不适用于任何类型,
然后给定的模板比其他模板更专业。
这样,以下第一个模板也比第二个模板
更专业template<typename T> void f(T*);
template<typename T> void f(T);
请注意,第一个模板的参数至少与第二个模板一样专用,但未定义为“更专业” - 该术语仅适用于两个参数均为参考且某些条件适用的情况(参见第9段) 14.8.2.4)。这些规则显然不意味着遵循任何正式的订购法律。第二个模板至少与第一个模板不同。这意味着第二颗子弹适用,而不是第一颗子弹。
答案 1 :(得分:6)
此答案基于对标准段落的抽象语法树的错误解析。 “返回标准”部分中假设的条件分组结果不是预期的。预期的分组是Johannes Schaub在答案中表现出来的。
为什么当时没有任何一个人至少比相应的Ts更专业呢?
我同意你的看法,第二部分(实际上,第二部分条件)是多余的。
一些参考词汇:
让我们对逻辑有一些乐趣,并在一对相应参数的两个模板之间引入3个基本关系:
Ti
和Ui
,一个模板与另一个模板匹配,但不是,反之亦然。我将此标记为Ti < Ui
; Ti
和Ui
,一个模板与另一个模板匹配,反之亦然。我将此标记为Ti == Ui
; Ti
和Ui
,模板的无与特定参数的另一个匹配。我将此标记为T1 ~ U1
。例如,在下面的代码段中:
template<typename X> struct A { };
template<typename X> struct B { };
template<typename X> void foo(A<X>, X, A<X>) { } // 1
template<typename X> void foo(X, X, B<X>) { } // 2
对于第一个参数,(1)比(<
)(2)更专业;对于第二个参数,(1)同样专门用作(或“专门用作”,==
)(2);对于第三个参数,(1)是专门化 - 无法比较(~
)(2)。
让'现在定义派生关系:
Ti
或{{1>时,模板(1)至少与另一个模板(2)一样,用于各个参数Ui
和(Ti < Ui)
当(1)比(2)更专业或(1)与(2)一样专用时。因此,在上面的示例中,(Ti == Ui)
,T1 <= U1
和T2 <= U2
。返回标准:
在几个括号的帮助下,上面的引用变为(A&amp;&amp;(B1 || B2)):
[...]正在考虑的每种类型:
(给定的模板至少对所有类型和 更专业的一些类型)
U2 <= T2
(其他模板不适用于任何类型
AND
至少不适用于任何类型的)
根据参数类型 OR
和T1, ..., Tn
的相应序列给出两个要排序的模板,条件(A):
[...]给定的模板至少是所有类型的专用,更专门用于某些类型[...]
表示对于U1, ..., Un
中的每个i = 1..n
,Ti <= Ui
和某些j
,它适用1..n
更严格的条件。删除索引Tj < Uj
,这意味着对于每个参数:
i
这个条件与另一个条件(B)逻辑连接(“和”),这又是两个子条件(B1)和(B2)的逻辑分离(“或”)。让我们开始研究子条件(B1):
[...]另一个模板并不适用于任何类型的[...]
这意味着对于任何(T < U) || (T == U) // (A)
,i
永远不会出现这种情况,这意味着:
Ui < Ti
比Ti
(Ui
)更专业;或Ti < Ui
和Ti
同样专业(Ui
);或Ui == Ti
和Ti
是专业化无法比较的(Ui
):更正式:
Ui ~ Ti
现在让我们看看第二个子条件(B2),它与(B1)逻辑分离:
[...]至少不适用于任何类型[...]
这是对!(U < T) <==> (T < U) || (T == U) || (T ~ U) // (B1)
的否定,这意味着:
U <= T
换句话说,!(U <= T) <==> !((U == T) || (U < T)) ==> !(U == T) && !(U < T)
和T
不是同等专业的,U
也不比U
更专业。因此,剩下的唯一可能性是:
T
现在很明显(B2)暗示(B1),因为(B2)更具限制性。因此,它们的析取(B)将与(B1)一致,并且(B2)是多余的:
(T < U) || (T ~ U) // (B2)
但这里显而易见的是(A)比(B)更严格,因此(A)和(B)的结合等同于(A)。
<强>结论:强>
整个条件(B)是多余的。