什么时候一个模板比另一个更专业?"和"/"或"与逻辑混淆。



在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个基本关系:

  • 更专门化:对于参数TiUi,一个模板匹配另一个模板,但不匹配,反之亦然。我将把它标记为Ti < Ui;
  • 同样专门化的:对于参数TiUi,一个模板匹配另一个,反之亦然。我将把它标记为Ti == Ui;
  • specialize -incomparable:分别对于参数TiUinone中的一个模板与另一个模板匹配特定参数。我将其标记为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)对于各自的参数TiUi至少与另一个模板(2)一样专门化。因此,在上面的示例中,T1 <= U1, T2 <= U2U2 <= T2

回归标准:

在两个括号的帮助下,上面的引号变成了(a &&(B1 || B2)):

[…]:

(一个给定的模板至少对所有类型和

                                 AND 

(另一个模板没有更专门化的任何类型

                                 OR

至少对于任何类型)

给定两个模板按照参数类型T1, ..., TnU1, ..., Un的相应序列排序,条件(A):

[…给定的模板对于所有类型至少是专门化的,对于某些类型集则更专门化[…]

表示对于1..n中的每一个i = 1..nTi <= Ui以及部分j s,应用比Tj < Uj更严格的条件。删除索引i,这意味着对于每个参数:

(T < U) || (T == U) // (A)

这个条件与另一个条件(B)在逻辑上连接(and),而B又是两个子条件(B1)和(B2)的逻辑析取(or)。让我们开始检查子条件(B1):

[…[…]

这意味着对于任何i,都不会出现Ui < Ti,这意味着:

  • TiUi (Ti < Ui)更专门化;或
  • TiUi同样专门化(Ui == Ti);或
  • TiUi是专门化不可比较的(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)

所以换句话说,TU的专门化程度不一样,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)是多余的。

相关内容

  • 没有找到相关文章

最新更新