iam*_*ind 7 c++ templates class static-members
在给定的文件中,如果我有,
struct A { static int a; };
struct B { static int b; };
int A::a;
int B::b;
Run Code Online (Sandbox Code Playgroud)
然后,我总是可以期待A::a
之前被初始化B::b
.现在对于同一个文件,拿这个template
案子,
template<typename T>
struct X { static T t; };
template<typename T>
T X<T>::t;
Run Code Online (Sandbox Code Playgroud)
假设,X
进行实例化A
和B
及其static
成员使用的代码任意地方,X<A>::t
并且X<B>::t
,那应该是初始化时的顺序template
静态成员X<T>::t;
?它定义明确吗?
只要模板只有一个定义(例如,您只有一个翻译单元),它就是明确定义的。静态成员按照模板特化在需要静态数据成员定义的上下文中实例化的顺序进行初始化。来自 C++03 标准的 \xc2\xa714.7.1/1 [temp.inst](强调我的):
\n\n\n\n\n除非类模板特化已显式实例化 (14.7.2) 或显式特化 (14.7.3),否则当在需要完全定义的对象类型的上下文中引用特化或完整性时,类模板特化将被隐式实例化类类型的类型影响程序的语义。类模板特化的隐式实例化会导致类成员函数、成员类、静态数据成员和成员模板的声明的隐式实例化,但不会导致定义或默认参数的隐式实例化;它会导致成员匿名联合定义的隐式实例化。除非类模板或成员模板的成员已显式实例化或显式特化,否则当在需要成员定义存在的上下文中引用特化时,会隐式实例化该成员的特化;特别是,静态数据成员的初始化(以及任何相关的副作用)不会发生,除非静态数据成员本身以需要静态数据成员的定义存在的方式使用。
\n
\xc2\xa714.7.1/7 还指出:
\n\n\n\n\n类模板的隐式实例化不会导致该类的任何静态数据成员被隐式实例化。
\n
但是,当您有多个定义模板的翻译单元时,事情会变得更加复杂。\xc2\xa73.2/5 [basic.def.odr] 指出:
\n\n\n\n\n类类型(第 9 条)、枚举类型(7.2)、具有外部链接的内联函数(7.1.2)、类模板(第 14 条)、非静态函数模板(14.5.5)可以有多个定义、类模板的静态数据成员(14.5.1.3)、类模板的成员函数(14.5.1.1)或程序中未指定某些模板参数的模板特化(14.7、14.5.4),前提是每个定义出现在不同的翻译单元中,并且定义满足以下要求。给定这样一个名为 D 的实体,在多个翻译单元中定义,则
\n\n(条件清单...)
\n\n如果 D 的定义满足所有这些要求,则程序的行为应如同 D 的单个定义一样。如果 D 的定义不满足这些要求,则行为未定义。
\n
请注意,该标准没有指定将哪个定义作为单个定义,只是选择了某个定义。因此,如果多个翻译单元以不同的顺序实例化模板,则无法保证初始化的顺序。
\n