繁体   English   中英

class模板中static内联成员变量的初始化顺序(C++17)

[英]Initialization order of static inline member variables in class templates (C++17)

I am working on a code where I need a static member variable of some class to be initialized using a static variable of an instance of a class template. 我知道 static 初始化订单惨败,并发现了几个关于该问题的讨论,但没有一个真正帮助我解决我的问题。 我什至不知道为什么这对我来说是个问题。

这是一个最小的例子,它重现了我从代码中得到的错误:

#include <string>
#include <map>


template<class T>
class Foo {

private:

    static inline std::map<std::string, T> map_ = {};
    
public:
    
    static bool insert(const std::string& key, T value) {

        map_[key] = value;
        return true;
    }
};


using MyFoo = Foo<char>;

class Bar {
    static inline bool baz_ = MyFoo::insert("baz", 'A');
};


int main() {
    // This works just fine if the definition of Bar::baz_ in line 24 is removed
    //MyFoo::insert("baz", 'A');
    return 0;
}

使用 C++17 标准编译完成,出现 0 个警告和 0 个错误。 但是,在执行程序时,调用Foo::insert时会发生分段错误。 看来Foo::map_在那一点上没有初始化。 但是 static 变量不应该按照代码中定义的顺序进行初始化吗?

我还应该提到,没有模板的代码可以正常工作。 所以我想知道编译器是否以实际 class 定义在Bar之后的方式实例化模板。 可能是这样的问题,还是编译器在这种情况下恰好做了“正确”的事情?

static 模板特化的 static 数据成员的动态初始化(如果它们未显式特化)与任何其他动态初始化完全无序(不确定排序)。 成员是否inline无关紧要,其他动态初始化是否也是 class 模板特化的 static 数据成员无关紧要,实例化点在哪里也无关紧要static 数据成员的定义和定义位于翻译单元中。

因此,无法保证Foo<char>::map_Bar::baz_之前初始化。

Instead use the common idiom of using a static member function containing the static member as a local static variable instead:

static auto& map_() {
    static std::map<std::string, T> map = {};
    return map;
}

// replace `map_` with `map_()` everywhere else

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM