sta*_*cpp 14 c++ templates language-lawyer
N4527 14.5.5.1 [temp.class.spec.match]
2如果可以从实际模板参数列表推导出部分特化的模板参数,则部分特化匹配给定的实际模板参数列表.
Run Code Online (Sandbox Code Playgroud)template<class T1, class T2, int I> class A { }; // #1 template<class T, int I> class A<T, T*, I> { }; // #2 template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3 template<class T> class A<int, T*, 5> { }; // #4 template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5 A<int, int, 1> a1; // uses #1 A<int, int*, 1> a2; // uses #2, T is int, I is 1 A<int, char*, 5> a3; // uses #4, T is char A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1 A<int*, int*, 2> a5; // ambiguous: matches #3 and #53还可以从主模板的非类型参数的实际模板参数的值推导出非类型模板参数.[例子:上述声明
a2. - 末端的例子]4在引用类模板特化的类型名称中(例如,
A<int, int, 1>)参数列表应与主模板的模板参数列表匹配.专门化的模板参数是从主模板的参数推导出来的.
在rule3中,示例显示I是从第三个实际模板参数推导出来的1,这就是rule2所说的内容.因此,作为rule4的第二句,我认为重复规则2所说的.
它们之间有什么区别(规则2,规则3和规则4)?
换句话说,我们已经有了rule2,rule3的意图(含义)和rule4的第二句是什么,为什么他们在这里?
我认为,规则[temp.class.spec.match] 14.5.5.1\2可以这样重写,而不改变其主旨:
[temp.class.spec.match] 14.5.5.1\2(已修改)
如果可以根据 14.8.2.5 从实际模板参数列表推导出部分特化的模板参数,则部分特化与给定的实际模板参数列表匹配,其中 P 是根据其 simple-template-id 的部分特化的参数列表A 是实际的模板参数列表。
规则[temp.deduct.type] 14.8.2.5\1仅定义从类型推导的过程(尽管我不确定模板),因此需要规则[temp.class.spec.match] 14.5 .5.1\3,它添加到14.5.5.1\2具有主模板的非类型模板参数的情况,这些情况在部分特化中没有(部分)特化。
正如您在上面的评论(1 , 2 )中指出的那样,规则[temp.class.spec.match] 14.5.5.1\4只是澄清,template-id中的模板参数对应于主模板的模板参数template,而不是它的部分特化,它可能有不同的template-parameter-list。此外,该规则的第二句很可能声称主模板( 14.5.5\4 )的隐式模板参数列表是根据[temp.deduct.type] 14.8.2.5\9从实际中推导出来的(!)参数列表。因此,短语“主模板的隐式模板参数列表”和“专业化的模板参数”暗示着同一件事,而短语“主模板的参数”和“实际模板参数列表”暗示着另一件同一件事......但作者也可能打算这样写:
[temp.class.spec.match] 14.5.5.1\4(已修改)
在引用类模板特化的类型名称中,参数列表应与主模板的模板参数列表相匹配。部分特化的模板参数是从主模板的参数推导出来的。
任何...