在 C++11 之前,我们只能对整型或枚举类型的静态 const 成员进行类内初始化。Stroustrup 在他的 C++ FAQ 中讨论了这一点,并给出了以下示例:
class Y {
const int c3 = 7; // error: not static
static int c4 = 7; // error: not const
static const float c5 = 7; // error: not integral
};
以及以下推理:
那么为什么会存在这些不方便的限制呢?一个类通常在头文件中声明,并且头文件通常包含在许多翻译单元中。但是,为了避免复杂的链接器规则,C++ 要求每个对象都有唯一的定义。如果 C++ 允许在类内定义需要作为对象存储在内存中的实体,则该规则将被打破。
但是,C++11 放宽了这些限制,允许对非静态成员进行类内初始化(第 12.6.2/8 节):
在非委托构造函数中,如果给定的非静态数据成员或基类不是由mem-initializer-id指定的(包括由于构造函数没有ctor-initializer而没有mem-initializer-list的情况)并且实体不是抽象类(10.4)的虚拟基类,则
- 如果实体是具有大括号或相等初始化器的非静态数据成员,则实体按照 8.5 中的规定进行初始化;
- 否则,如果实体是变体成员(9.5),则不执行初始化;
- 否则,实体被默认初始化(8.5)。
9.4.2 节还允许对非常量静态成员进行类内初始化,如果它们用说明constexpr
符标记的话。
那么我们在 C++03 中受到限制的原因是什么?我们只是简单地接受“复杂的链接器规则”还是进行了其他更改以使其更易于实现?