对于静态成员初始化,我使用嵌套帮助程序结构,对于非模板类可以正常工作。 但是,如果封闭类由模板参数化,则嵌套的初始化类未实例化,如果辅助对象未在主代码中访问。 为了说明,一个简化的例子(在我的情况下,我需要初始化一个向量)。C++静态成员初始化(内部模板乐趣)
#include <string>
#include <iostream>
struct A
{
struct InitHelper
{
InitHelper()
{
A::mA = "Hello, I'm A.";
}
};
static std::string mA;
static InitHelper mInit;
static const std::string& getA(){ return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;
template<class T>
struct B
{
struct InitHelper
{
InitHelper()
{
B<T>::mB = "Hello, I'm B."; // [3]
}
};
static std::string mB;
static InitHelper mInit;
static const std::string& getB() { return mB; }
static InitHelper& getHelper(){ return mInit; }
};
template<class T>
std::string B<T>::mB; //[4]
template<class T>
typename B<T>::InitHelper B<T>::mInit;
int main(int argc, char* argv[])
{
std::cout << "A = " << A::getA() << std::endl;
// std::cout << "B = " << B<int>::getB() << std::endl; // [1]
// B<int>::getHelper(); // [2]
}
随着克++ 4.4.1:
[1]和[2]表示:
A = Hello, I'm A.
按预期工作
[1]未注释:
A = Hello, I'm A. B =
我所期望的,该InitHelper初始化的mB
- [1]和[2]未注释:
A = Hello, I'm A. B = Hello, I'm B.
按预期工作 - [1]评论,[2]未注释:
段错误在静态初始化阶段在[3]
因此我的问题:这是一个编译器错误还是坐在监视器和椅子之间的错误? 如果后者是这种情况:是否有一个优雅的解决方案(即没有显式调用静态初始化方法)?
更新I:
这似乎是一个期望的行为(如在ISO/IEC C++ 2003标准,14.7.1定义):
除非类模板或一个成员成员模板已被显式实例化或明确专用化,当需要成员定义存在的上下文中引用专用化时,成员的专业化被隐式实例化;特别是静态数据成员的初始化(以及任何相关的副作用)不会发生,除非静态数据成员本身以需要静态数据成员定义存在的方式使用。
Visual Studio 2008中具有相同的行为(在静态初始化-segfault) – 2009-11-30 11:08:27
你为什么不只是写的std ::串B :: MB = “你好,我是B”? –
2009-11-30 11:11:27
好吧,我看到在实际情况下,您需要无损伤媒介,抱歉。 – 2009-11-30 11:12:09