属于模板类的成员模板的C ++显式特化

时间:2018-04-14 14:44:43

标签: c++ language-lawyer template-specialization

在当前的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)是实体(模板)本身的特化。

标准是否提到了这种差异,还是这两种专业化被称为相同?

谢谢。

1 个答案:

答案 0 :(得分:1)

首先,您的#3等同于引用示例中的第一个特化,除了标准f在其签名中使用类的模板参数 - 大概是为了说明,因为签名必须匹配专业化,可能需要在专门化声明中重复该类的模板参数。

然后,区别在于当A<T>T时,#1是int成员的特化 - 一种写作的简写A<int>本身的特化,与主模板大致相同。特别是,为了避免误导,专用成员的签名必须与主模板的(实例化)保持不变。在这种情况下,这意味着它仍然是模板。

另一方面,#2是发生成为A<int>成员的模板的特化 - 专业化是A<int>::g1本身,不是“ A<T>::g1 Tint时的{{1}}与#1相同。这当然仅适用于成员是模板的情况,与#3不同。 (在这种情况下,#2是#1声明的模板的特化!)

[temp.expl.spec] / 15的部分要点是这两个案例 语法上没有强烈区分。差异在很大程度上是学术性的:对于某些论点,两者都是templated entity的外科变化。