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

时间:2013-03-29 11:15:04

标签: c++ c++11 partial-ordering

在C ++ 11草案的14.8.2.4p10中,写了

  

如果考虑的每种类型,给定的模板至少对所有类型都是专用的,对某些类型的集合更专用,而另一种模板对于任何类型都不是更专用的,或者至少不适用于任何类型,那么给定的模板比其他模板更专业。

为什么有“或者至少不适合任何类型”?据我所知,如果我们有一个类型列表

T1, T2, T3
U1, U2, U3

如果所有Ts至少都是专业的,有些则更专业。并且没有一个人更专业,那么在我看来,从逻辑上讲,整个T的集合比U集合更专业。那么为什么当没有一个人至少比相应的Ts更专业时,会提到回退?

2 个答案:

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

  • 更专业:对于参数TiUi,一个模板与另一个模板匹配,但不是,反之亦然。我将此标记为Ti < Ui;
  • 同样专业:对于参数TiUi,一个模板与另一个模板匹配反之亦然。我将此标记为Ti == Ui;
  • 专业化无法比较:对于参数TiUi,模板的与特定参数的另一个匹配。我将此标记为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 <= U1T2 <= U2

返回标准:

在几个括号的帮助下,上面的引用变为(A&amp;&amp;(B1 || B2)):

  

[...]正在考虑的每种类型:

     

给定的模板至少对所有类型和   更专业的一些类型

U2 <= T2
     

其他模板不适用于任何类型

                                 AND 
     

至少不适用于任何类型的

根据参数类型 OR T1, ..., Tn的相应序列给出两个要排序的模板,条件(A):

  

[...]给定的模板至少是所有类型的专用,更专门用于某些类型[...]

表示对于U1, ..., Un中的每个i = 1..nTi <= Ui和某些j,它适用1..n更严格的条件。删除索引Tj < Uj,这意味着对于每个参数:

i

这个条件与另一个条件(B)逻辑连接(“和”),这又是两个子条件(B1)和(B2)的逻辑分离(“或”)。让我们开始研究子条件(B1):

  

[...]另一个模板并不适用于任何类型的[...]

这意味着对于任何(T < U) || (T == U) // (A) i永远不会出现这种情况,这意味着:

  • Ui < TiTiUi)更专业;或
  • Ti < UiTi同样专业(Ui);或
  • Ui == TiTi是专业化无法比较的(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)是多余的。