模板类中的静态成员初始化复杂性
C 中的静态成员初始化是一种广泛使用的技术,但在处理时可能会变得复杂模板化的类。在非模板化类中,可以采用嵌套辅助结构进行初始化,但当封闭类是模板化时,这种方法就不够了。
考虑以下简化示例:
struct A
{
static std::string mA;
static InitHelper mInit;
static const std::string& getA() { return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;
template
struct B
{
static std::string mB;
static InitHelper mInit;
static const std::string& getB() { return mB; }
static InitHelper& getHelper() { return mInit; }
};
template
std::string B::mB;
template
typename B::InitHelper B::mInit;
int main()
{
std::cout ::getB() ::getHelper(); // [2]
}
预期行为:
当 [1] 未注释且 [2] 已注释时,我们期望 B
实际行为:
原因差异:
根据 ISO/IEC C 2003 标准,当在需要其定义存在的上下文中引用时,模板成员会被隐式实例化。但是,静态数据成员初始化(以及任何相关的副作用)仅在显式使用静态数据成员时发生。这意味着,如果模板成员仅在未实例化的模板中或在不需要其完全实例化的其他上下文中引用,则其静态数据成员将不会被初始化。
在示例中,B
解决方案:
该标准禁止显式专用类模板静态数据成员的定义进行有序初始化,而其他类模板静态数据成员进行无序初始化。为了确保一致的初始化顺序,必须使用显式特化。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3