姬長信(Redy)

C静态成员初始化(模板内部有趣)


对于静态成员初始化,我使用嵌套的帮助器结构,它适用于非模板化的类.
但是,如果封闭类由模板参数化,则如果未在主代码中访问辅助对象,则不会实例化嵌套初始化类.
为了说明,一个简化的例子(在我的例子中,我需要初始化一个向量).
#include 
#include 

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
struct B
{
    struct InitHelper
    {
        InitHelper()
        {
            B::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
std::string B::mB; //[4]
template
typename B::InitHelper B::mInit;


int main(int argc, char* argv[])
{
    std::cout ::getB() ::getHelper();    // [2]
}

随着g 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]未注释:
Segfault在[3]的静态初始化阶段

因此我的问题是:这是一个编译器错误还是坐在显示器和主席之间的错误?
如果是后者:是否有一个优雅的解决方案(即没有明确调用静态初始化方法)?

更新I:
这似乎是一种理想的行为(如ISO / IEC C 2003标准14.7.1中所定义):

Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.