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