クラス内の非const static
メンバーまたはstatic
配列を初期化できないのはなぜですか?
class A
{
static const int a = 3;
static int b = 3;
static const int c[2] = { 1, 2 };
static int d[2] = { 1, 2 };
};
int main()
{
A a;
return 0;
}
コンパイラは次のエラーを発行します。
g++ main.cpp
main.cpp:4:17: error: ISO C++ forbids in-class initialization of non-const static member ‘b’
main.cpp:5:26: error: a brace-enclosed initializer is not allowed here before ‘{’ token
main.cpp:5:33: error: invalid in-class initialization of static data member of non-integral type ‘const int [2]’
main.cpp:6:20: error: a brace-enclosed initializer is not allowed here before ‘{’ token
main.cpp:6:27: error: invalid in-class initialization of static data member of non-integral type ‘int [2]’
2つの質問があります。
static
データメンバーを初期化できないのはなぜですか?static
配列、さらにはconst
配列でも初期化できないのはなぜですか?これは、単純なリンカーの昔の遺物のようです。回避策として、静的メソッドで静的変数を使用できます。
// header.hxx
#include <vector>
class Class {
public:
static std::vector<int> & replacement_for_initialized_static_non_const_variable() {
static std::vector<int> Static {42, 0, 1900, 1998};
return Static;
}
};
int compilation_unit_a();
そして
// compilation_unit_a.cxx
#include "header.hxx"
int compilation_unit_a() {
return Class::replacement_for_initialized_static_non_const_variable()[1]++;
}
そして
// main.cxx
#include "header.hxx"
#include <iostream>
int main() {
std::cout
<< compilation_unit_a()
<< Class::replacement_for_initialized_static_non_const_variable()[1]++
<< compilation_unit_a()
<< Class::replacement_for_initialized_static_non_const_variable()[1]++
<< std::endl;
}
ビルド:
g++ -std=gnu++0x -save-temps=obj -c compilation_unit_a.cxx
g++ -std=gnu++0x -o main main.cxx compilation_unit_a.o
実行:
./main
これが機能するという事実(一貫して、クラス定義が異なるコンパイル単位に含まれている場合でも)は、現在のリンカー(gcc 4.9.2)が実際に十分にスマートであることを示しています。
おかしい:腕に0123
とx86に3210
を印刷します。
宣言と定義を混同しないようにするためだと思います。 (ファイルを複数の場所に含める場合に発生する可能性のある問題について考えてください。)