【问题标题】:C++ explicit specialization of member template belonging to template class属于模板类的成员模板的 C++ 显式特化
【发布时间】:2018-04-14 14:44:43
【问题描述】:

在当前的 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) 的专门版本中的函数模板,而在 (2) 中,g1 本身似乎专门用于自己设置的模板参数((int, from A), 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) 是实体(模板)本身的特化。

标准是否提到了这种差异,或者这两种专业化是否相同?

谢谢。

【问题讨论】:

  • 它们不一样。
  • 你能告诉我标准如何以及在哪里区分两者吗?
  • 我不是语言律师。 (1) 是部分特化,因为它仍然依赖于模板类型。 (3) 是一个专业。
  • 也许我不应该从标准中选择示例。如果g1 被声明为:template void g1(U);,我相信它们都会是明确的特化。

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


【解决方案1】:

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

然后,区别在于 #1 是 A&lt;T&gt;成员 的特化,而 Tint — 一种写 A&lt;int&gt; 自身特化的简写这与主模板基本相同。特别是,为了避免误导,被专门化的成员的签名必须与主模板(的实例化)保持不变。在这种情况下,这意味着它仍然是一个模板。

另一方面,#2 是模板的特化,碰巧A&lt;int&gt; 的成员——特化是A&lt;int&gt;::g1 本身,而不是“A&lt;T&gt;::g1”的成员Tint”,与 #1 一样。这当然只适用于成员是模板的情况,这与#3 不同。 (在这种情况下,#2 是由 #1 声明的模板的特化!)

[temp.expl.spec]/15 的部分观点是这两种情况在语法上不是强烈区分。区别主要是学术上的:对于某些论点,两者都是对templated entity 的外科手术。

【讨论】:

  • 感谢您的回答。我知道它们意味着不同的东西,这就是为什么我认为这种差异会在标准中的某个地方明确提到。我有个问题。您说“特别是,为了避免误导,被专门化的成员的签名必须与主模板的(实例化)保持不变。”。我将其理解为:“当您明确专门化类模板的成员时,其签名必须与主模板中的签名保持相同”。这是正确的吗? [继续]
  • 如果是这样,那么为什么temp.expl.spec p.5 使用以下措辞:“[...] 但是,template 用于定义明确专门化的成员类模板的成员,该模板专门化为一个类模板。”?如果它的签名不能改变,那么我能想到的唯一另一种可能性是模板是否也专门用于它自己的模板参数,即如 #2 中那样。这是正确的吗?
  • @user42768:至于提到区别,我从 /15 直觉的伪官方术语是“成员的显式专业化”(可能恰好是模板)和“显式专业化(模板)”(可能恰好是成员)。
  • @user42768:关于固定签名:是的,这就是我的意思,但是关于什么构成签名有implementation divergence:GCC 接受该代码,但如果专业化不是模板则拒绝完全没有。
  • @user42768: 至于 /5,我认为它区别于 defining a member 的专门化而不是,用于成员模板的某些模板参数集(并且在特定的包含模板的特化,根据需要)。
猜你喜欢
  • 1970-01-01
  • 2013-12-20
  • 2011-07-27
  • 2020-11-17
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
相关资源
最近更新 更多