web-dev-qa-db-ja.com

クラスの非const静的メンバーまたは静的配列を初期化できないのはなぜですか?

クラス内の非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つの質問があります。

  1. クラスのstaticデータメンバーを初期化できないのはなぜですか?
  2. クラス内のstatic配列、さらにはconst配列でも初期化できないのはなぜですか?
91
Yishu Fang

これは、単純なリンカーの昔の遺物のようです。回避策として、静的メソッドで静的変数を使用できます。

// 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を印刷します。

3
not-a-user

宣言と定義を混同しないようにするためだと思います。 (ファイルを複数の場所に含める場合に発生する可能性のある問題について考えてください。)

1
Mehrdad