[英]Can initialization order of global variables across TUs be forced with C++17 inline members?
[英]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.