在当前的C ++标准草案中,this paragraph中的这个示例属于与模板显式特化相关的部分:
template<class T> struct A {
void f(T);
template<class X1> void g1(T, X1);
template<class X2> void g2(T, X2);
void h(T) { }
};
// specialization
template<> void A<int>::f(int);
// out of class member template definition
template<class T> template<class X1> void A<T>::g1(T, X1) { }
// member template specialization
template<> template<class X1> void A<int>::g1(int, X1); //(1)
// member template specialization
template<> template<>
void A<int>::g1(int, char); //(2)
在(1)中似乎更像g1
专门用作A(A&lt; int&gt;)的专用版本中的函数模板,而在(2)中看起来像{{1} }它本身专门用于它自己的set模板参数((int,来自A&lt; int&gt;),char)。
我发现这些专业化之间存在差异(同样,(1)感觉宣布新版本的g1
用于其“容器”g1
的“特殊版本” ,而(2)感觉就像A
本身(或关于它自己的模板参数)的专业化。
此外,请考虑以下示例:
g1
对我来说(1)和(3)是相同的“专业化类型”,一种与“容器”的特殊版本相关联,而(2)是实体(模板)本身的特化。
标准是否提到了这种差异,还是这两种专业化被称为相同?
谢谢。
答案 0 :(得分:1)
首先,您的#3等同于引用示例中的第一个特化,除了标准f
在其签名中使用类的模板参数 - 大概是为了说明,因为签名必须匹配专业化,可能需要在专门化声明中重复该类的模板参数。
然后,区别在于当A<T>
为T
时,#1是int
的成员的特化 - 一种写作的简写A<int>
本身的特化,与主模板大致相同。特别是,为了避免误导,专用成员的签名必须与主模板的(实例化)保持不变。在这种情况下,这意味着它仍然是模板。
另一方面,#2是发生成为A<int>
成员的模板的特化 - 专业化是A<int>::g1
本身,不是“ A<T>::g1
T
为int
时的{{1}}与#1相同。这当然仅适用于成员是模板的情况,与#3不同。 (在这种情况下,#2是#1声明的模板的特化!)
[temp.expl.spec] / 15的部分要点是这两个案例 语法上没有强烈区分。差异在很大程度上是学术性的:对于某些论点,两者都是templated entity的外科变化。