为什么std::map在类内部声明为静态内联并在早期使用时会崩溃



我多次发现,当std::map在类内声明为静态内联(C++17(时,

struct MyStruct
{
static inline std::map <A, B> mymap;
MyStruct(A& a, B& b)
{
mymap[a] = b;
}
};

如果MyStruct构造函数在第一次使用map成员时被提前调用,即在main之前调用,它将崩溃。

如果std::map以不同的方式声明,即

struct MyStruct
{
static std::map <A, B>& mymap()
{
static std::map <A, B> map;
return map;
}

MyStruct(A& a, B& b)
{
mymap()[a] = b;
}
};

则不会发生崩溃。

我本以为在这两种情况下,映射都会在允许继续调用MyStruct构造函数之前初始化。

有人能解释一下这里发生了什么吗?

有效地声明static inline类成员ODR在一些随机选择的翻译单元中定义该类成员,该单元形成最终可执行文件。

在这一点上,当类成员以您描述的方式在翻译单元中被引用时,静态初始化顺序Fiasco成为一个因素。

这会导致未定义的行为。

函数作用域的static类实例是一种众所周知的技术,用于克服静态初始化顺序的失败。函数范围的static对象具有定义良好的初始化语义:第一次从任何转换单元调用函数时。

相关内容

  • 没有找到相关文章

最新更新