在c++ 11草案的14.8.2.4p10中,写着
如果对于所考虑的每种类型,给定模板至少对所有类型都是专门化的,对某些类型集更专门化,而另一个模板对任何类型都不是专门化的,或者至少对任何类型都不是专门化的,则给定模板比另一个模板更专门化。
为什么会有一个"或至少不是为任何类型专门的"?据我所知,如果我们有一个类型列表
T1, T2, T3
U1, U2, U3
如果所有t至少都是一样专门化的,有些更专门化。没有一个U更专门化,那么在我看来,从逻辑上讲,T的集合作为一个整体比U的集合更专门化。为什么在没有一个美国至少比相应的t更专业的情况下,还有提到的退路?
更新:这已被添加为官方c++问题
我终于明白了如何阅读这段有问题的文章。下面我给它加了项目符号
对于每个被考虑的类型,给定的模板至少对所有类型都是专门化的,并且
- 对某些类型更专门化,而另一个模板对任何类型都不专门化,或者
- {另一个模板}至少对任何类型都没有专门化,
则给定模板比另一个模板更专门化。
这样,下面的第一个模板也比第二个模板更专门化
template<typename T> void f(T*);
template<typename T> void f(T);
请注意,第一个模板的形参至少与第二个模板一样专门化,但没有定义为"更专门化"——这个术语仅适用于两个形参都是引用并且适用某些条件的情况(参见14.8.2.4的第9段)。这些规则显然是而不是意味着遵循任何正式的排序定律。第二个模板至少不像第一个模板那样专门化。这意味着第二个子弹适用,而不是第一个子弹。
这个答案是基于对标准段落抽象语法树的错误解析。"回到标准"一节中假设的条件分组结果并不是预期的。预期的分组是Johannes Schaub在他的回答中所显示的。
为什么当没有一个u至少比对应的t更专业的时候,还有提到的退一步?
我同意你的观点,第二部分(实际上,整个第二个条件)是多余的。
参考词汇:
让我们来玩一下逻辑,并介绍一对对应参数的两个模板之间的3个基本关系:
-
比更专门化:对于参数
Ti
和Ui
,一个模板匹配另一个模板,但不匹配,反之亦然。我将把它标记为Ti < Ui
; -
同样专门化的:对于参数
Ti
和Ui
,一个模板匹配另一个和,反之亦然。我将把它标记为Ti == Ui
; -
specialize -incomparable:分别对于参数
Ti
和Ui
, none中的一个模板与另一个模板匹配特定参数。我将其标记为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)与(或"as specialized as", ==
)(2)相同;对于第三个参数,(1)是专门化——无法与(~
)(2)相比。
现在定义一个派生关系:
- 当
(Ti < Ui)
或(Ti == Ui)
时,即当(1)比(2)更专门化或(1)与(2)一样专门化时,模板(1)对于各自的参数Ti
和Ui
至少与另一个模板(2)一样专门化。因此,在上面的示例中,T1 <= U1
,T2 <= U2
和U2 <= T2
。
回归标准:
在两个括号的帮助下,上面的引号变成了(a &&(B1 || B2)):
[…]:
(一个给定的模板至少对所有类型和
AND
(另一个模板没有更专门化的任何类型
OR
至少对于任何类型)
给定两个模板按照参数类型T1, ..., Tn
和U1, ..., Un
的相应序列排序,条件(A):
[…给定的模板对于所有类型至少是专门化的,对于某些类型集则更专门化[…]
表示对于1..n
中的每一个i = 1..n
、Ti <= Ui
以及部分j
s,应用比Tj < Uj
更严格的条件。删除索引i
,这意味着对于每个参数:
(T < U) || (T == U) // (A)
这个条件与另一个条件(B)在逻辑上连接(and),而B又是两个子条件(B1)和(B2)的逻辑析取(or)。让我们开始检查子条件(B1):
[…[…]
这意味着对于任何i
,都不会出现Ui < Ti
,这意味着:
-
Ti
比Ui
(Ti < Ui
)更专门化;或 -
Ti
和Ui
同样专门化(Ui == Ti
);或 -
Ti
和Ui
是专门化不可比较的(Ui ~ Ti
):
更正式:
!(U < T) <==> (T < U) || (T == U) || (T ~ U) // (B1)
现在让我们看看第二个子条件(B2),它与(B1)处于逻辑析取中:
[…[…]至少对于任何类型都没有那么专门化[/p>
这是U <= T
的否定,意思是:
!(U <= T) <==> !((U == T) || (U < T)) ==> !(U == T) && !(U < T)
所以换句话说,T
和U
的专门化程度不一样,U
也不比T
更专门化。因此,剩下的唯一可能是:
(T < U) || (T ~ U) // (B2)
现在很明显,(B2)暗示(B1),因为(B2)更具限制性。因此,它们的分析(B)将与(B1)重合,(B2)是冗余的:
(T < U) || (T ~ U) || (T == U) // (B)
但同样明显的是,(A)比(B)更严格,因此(A)和(B)的合取等价于(A)。
结论:
整个条件(B)是多余的。