模板类静态成员变量应该在.h文件中定义

Noa*_*ahR 11 c++ standards static templates member

如果模板类定义包含依赖于模板类型的静态成员变量,我不确定应该采用什么样的可靠行为?

在我的例子中,最好将静态成员的定义放在与类定义相同的.h文件中,因为

  1. 我希望这个类对于我目前不知道的许多模板数据类型是通用的.
  2. 我希望在我的程序中只为每个给定的模板类型共享一个静态成员实例.(一个为所有MyClass<int>,一个为所有MyClass<double>,等等.

我可以最简单地说,在使用gcc 4.3编译时,此链接中列出的代码完全符合我的要求.这种行为是否符合C++标准,以便在使用其他编译器时可以依赖它?

该链接不是我的代码,而是CodeMedic此处讨论的一个反例.我发现其他几个辩论这样的一个,但没有,我认为定论.

我认为链接器正在整合找到的多个定义(在示例a.o和中b.o ).这是必需/可靠的链接器行为吗?

Ker*_* SB 20

从N3290,14.6:

除非明确地实例化相应的专业化,否则应在每个翻译单元中定义类模板的静态数据成员,其中隐式实例化[...].

通常,您将静态成员定义与模板类定义一起放在头文件中:

template <typename T>
class Foo
{
  static int n;                       // declaration
};

template <typename T> int Foo<T>::n;  // definition
Run Code Online (Sandbox Code Playgroud)

扩展特许权:如果您计划在代码中使用显式实例化,例如:

template <> int Foo<int>::n = 12;
Run Code Online (Sandbox Code Playgroud)

那么你不能把模板化的定义放在标题中,如果Foo<int>它还用在除包含显式实例化的TU之外的其他TU中,那么你就可以获得多个定义.

但是,如果您确实需要为所有可能的参数设置初始值而不使用显式实例化,则必须将其放在标头中,例如使用TMP:

// in the header
template <typename T> int Foo<T>::n = GetInitialValue<T>::value;  // definition + initialization
Run Code Online (Sandbox Code Playgroud)