当前位置: 首页 > 知识库问答 >
问题:

关于类模板成员显式专门化的困惑

史骏祥
2023-03-14
template<class T> struct A {
  struct B { };
  template<class U> struct C { 
      void show();
  };
};

template<>
template<>
void A<int>::C<int>::show(){  //#1

}

int main(){

}

考虑上面的代码,在#1中,它是成员类模板成员的明确专门化定义。一些规则将适用于以下规定:

临时雇员爆炸。规格#5

显式特化类的成员不会从类模板的成员声明中隐式实例化;相反,如果需要定义,则应显式定义类模板特化的成员本身。在这种情况下,类模板显式特化的定义应在定义成员时处于范围内。显式特化类的定义与生成的特化的定义无关。也就是说,其成员不必与生成的特化的成员具有相同的名称、类型等。显式特化类模板的成员的定义方式与普通类的成员相同,并且不使用模板

首先,什么是显式专用类?它是指具有显式专门化声明的实体吗?似乎这并不意味着它,请看显式专用类部分中的示例

template<> template<> class A<int>::B<double>;

根据这个例子,A

请注意强调的部分,这意味着封闭类模板显式专门化应出现在其成员的显式专门化定义的相同范围内。成员是在全局范围内定义的,但是A没有任何明确的专门化定义

顺便说一下,作为一个相反的例子:

template<class T> struct A {
  struct B { };
  template<class U> struct C { 
      void show();
  };
};

template<>
template<typename U>
struct A<int>::C{  //#2
    void show();
};

template<>
template<typename U>
void A<int>::C<U>::show(){  //#3

}

int main(){

}

为什么这样的代码需要在#3之前对类模板C进行显式特化,这样的两个示例有什么区别?

“明确专业化类”一词在本节中不清楚,

temp.expl.spec#15

成员或成员模板可以嵌套在许多封闭类模板中。在此类成员的明确专业化中,成员声明前应附有模板

[ Example:  
template<class T1> class A {
  template<class T2> class B {
    void mf();
  };
};
template<> template<> class A<int>::B<double>;
template<> template<> void A<char>::B<char>::mf();
— end example ]  

显式专门化类是什么意思,它指的是具有显式专门化声明的实体还是其他什么?似乎对A没有明确的专门化


共有1个答案

赵炯
2023-03-14

这里没有混淆,你必须根据语法结构解析这些语句(C和英语)。源代码是用人类可以理解的语言描述程序。编程语言是人类合作的工具。

CWG529需要通过改变措辞来直观地理解模板ID的顺序和内容。

在这里,您用模板参数T声明了类A的模板,其中包含类B,用模板参数U声明了模板类C的嵌套声明,其中包含一个方法show()

template<class T> struct A {
  struct B { };
  template<class U> struct C { 
      void show();
  };
};

在这里,您声明,对于具有T=int的显式专用模板类A(需要先声明它),有一个模板类C包含方法show()

template<>
template<typename U>
struct A<int>::C{  //#2
    void show();
};

这个声明与前面的声明并不矛盾,但是因为它是A类的特化,所以它可能会扩展它!您可以这样做:

template<>
template<typename U>
struct A<int>::C{  //#4
    void hide();
};

这意味着对于任何具有T=int的A,都有一个模板类C,它获得了成员hide()。但其他A的模板类C的成员为show()。之前的声明是什么,它消除了关于C内容的任何疑问,以实现A的专业化。

现在,它只为A中包含的所有C定义成员函数show()

template<>
template<typename U>
void A<int>::C<U>::show(){  //#3

}

这里没有C的显式专门化,C是show()的封闭类。memeber idshow()前面有一个非专用的模板idtemplate

省略第2部分在语义上等同于写作:

class C;

void C::show() { // ill-formed - C is an incomplete type.
}

我们知道所有的A都包含一些C类,但在专门的A中,我们没有对特定C类的完整定义

这句话实际上说明了

template<>
template<>
void A<int>::C<int>::show(){  //#1

}

任何矛盾、歧义或不确定性的可能性(除了未html" target="_blank">定义的行为)都会导致代码格式错误,规则旨在形成一个限制框架,应根据该框架检查代码。如果没有#2,在某个时刻#3后面可能会跟着#4,那么#3语句将变为非法,因此被视为非法#2和#4同时是同一事物的两个定义,如果它们出现在同一个单元中,也会导致格式错误的代码,或者如果它们出现在程序中的不同单元中,则会导致未定义的行为。

 类似资料:
  • 这里有一个最小的例子来说明我遇到的问题。 模板成员显式专用于基类中的。模板的代码是显式生成的,并在成员中调用。 我发现的第一个问题是: 该错误是由于在main中调用造成的。可以通过调用来避免这种情况。为什么在的实例中显然是不可见的?

  • 顺便说一句,我确实编译了以下内容,但是专门化在运行时没有像预期的那样工作。基类型和派生类型最终要经历的非专用版本。 正确的语法是什么?

  • 在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。

  • 我有以下模板方法: 但是我得到了那些奇怪的链接错误: /usr/lib/gcc/x86_64-redhat-linux/4.4。7/../../../../包括/c/4.4。7/例外:62:void MyStruct::readField(std::basic_istream)的多重定义 如何专门化此成员函数? 编辑 这种方法在以下方面起作用: 或者使用s或在类外使用

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案