【发布时间】:2022-09-17 04:06:49
【问题描述】:
我正在编写一个代码,我需要使用类模板实例的静态变量来初始化某个类的静态成员变量。我知道静态初始化顺序惨败,并发现了几个关于该问题的讨论,但没有一个真正帮助我解决我的问题。我什至不知道为什么这对我来说是个问题。
这是一个最小的示例,它重现了我从代码中得到的错误:
#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_ 那时还没有初始化。但是不应该按照代码中定义的顺序来初始化静态变量吗?
我还应该提到,没有模板的代码可以正常工作。所以我想知道编译器是否以在Bar 之后定义实际类的方式实例化模板。可能是这样的问题还是编译器在这种情况下恰好做了“正确”的事情?
标签: c++ templates static c++17 inline