C++11 より前は、整数型または列挙型の static 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 では、指定子でマークされている場合、非 const 静的メンバーのクラス内初期化も許可されていconstexpr
ます。
では、C++03 にあった制限の理由はどうなったのでしょうか? 「複雑なリンカ規則」を受け入れるだけですか、それともこれを実装しやすくするために何か他の変更を加えていますか?