在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)的虚拟基类,则
- 如果实体是具有brace-or-equal-initializer的非静态数据成员,则按照8.5中的指定进行初始化;
- 否则,如果实体是变量成员(9.5),则不执行初始化。
- 否则,该实体为默认初始化(8.5)。
9.4.2节还允许非常量静态成员的类内初始化(如果用说明constexpr
符标记)。
那么,我们在C ++ 03中受到限制的原因发生了什么?我们是否只是接受“复杂的链接器规则”,还是进行了其他更改以使其更容易实现?