在当前的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< int>)的专用版本中的函数模板,而在(2)中,似乎g1本身专用于其自己的设置模板参数( (int,from A< int>),char).
我发现这些专业之间存在差异(同样,(1)感觉就像声明新版本的g1用于其“容器”A的“特殊版本”,而(2)感觉就像g1的专业化本身(或关于其自己的模板参数).
此外,请考虑以下示例:
template<class T> struct A{
int f() { return 1; }
}
template<>
int A<int>::f() { return 2; } //(3)
对我(1)和(3)是相同的“专业化类型”,一种与“容器”的特殊版本相关联,而(2)是实体(模板)本身的特化.
标准是否提到这种差异还是这两种专业化被称为相同?
谢谢.
最佳答案 首先,你的#3等同于引用例子中的第一个特化,除了标准的f在其签名中使用类的模板参数 – 大概是为了说明,因为签名必须匹配专门化,类的模板参数可能需要在专业化宣言中重复.
然后,不同之处在于#1是A< T>的成员的特化.当T是int时 – 用于编写A< int>的特化的一种简写.本身与主要模板大致相同.特别是,为了避免误导,专用成员的签名必须与主模板的(实例化)保持不变.在这种情况下,这意味着它仍然是一个模板.
另一方面,#2是恰好是A< int>的成员的模板的特化 – 专业化是A< int> :: g1本身,而不是“A< T> :: g1当T是“对于#1”.这当然仅适用于成员是模板的情况,与#3不同. (在这种情况下,#2是#1声明的模板的特化!)
[temp.expl.spec] / 15的部分要点是这两种情况在语法上没有很强的区别.差异在很大程度上是学术性的:对于某些论点,两者都是templated entity的手术变化.