Stack Overflow 上有几个问题,类似于“为什么我不能在 C++ 中初始化静态数据成员”。大多数答案都引用标准告诉您可以做什么;那些试图回答为什么通常指向一个链接(现在看似不可用)的人 [编辑:实际上它是可用的,见下文] 在 Stroustrup 的网站上,他指出允许静态成员的类内初始化将违反单一定义规则(ODR )。
然而,这些答案似乎过于简单。编译器完全能够在需要时解决 ODR 问题。例如,考虑 C++ 标头中的以下内容:
struct SimpleExample
{
static const std::string str;
};
// This must appear in exactly one TU, not a header, or else violate the ODR
// const std::string SimpleExample::str = "String 1";
template <int I>
struct TemplateExample
{
static const std::string str;
};
// But this is fine in a header
template <int I>
const std::string TemplateExample<I>::str = "String 2";
如果我在多个翻译单元中进行实例化,编译器/链接器的魔法就会发挥作用,并且我会在最终的可执行文件中TemplateExample<0>
获得一份副本。TemplateExample<0>::str
所以我的问题是,考虑到编译器显然可以解决模板类的静态成员的 ODR 问题,为什么它不能对非模板类也这样做呢?
编辑:Stroustrup 常见问题解答可在此处获得。相关语句是:
但是,为了避免复杂的链接器规则,C++ 要求每个对象都有唯一的定义。如果 C++ 允许对需要作为对象存储在内存中的实体进行类内定义,则该规则将被打破
然而,那些“复杂的链接器规则”似乎确实存在并且在模板案例中使用,那么为什么不在简单案例中呢?