10

gcc 4.5.1、SuSE Linux i686

次のコードがあるとします。

template<typename realT> class B
{
public:
    B() {std::cout << "B()" << std::endl;}
};

template<typename realT> class A
{
public:
    static B<realT> static_var;
};

template<typename realT> B<realT> A<realT>::static_var;
template<> B<float> A<float>::static_var;
template<> B<double> A<double>::static_var;

int main()
{
    A<float> test;
    return 0;
}

この場合、stdout には何も出力されません。コンパイラは、クラス A の float および double 特殊化を初期化するコードを生成しません。

しかし..次のように初期化を変更すると:

template<> B<float> A<float>::static_var = B<float>();
template<> B<double> A<double>::static_var = B<double>();

コンパイラはそのようなコードを生成し、出力には二重の「B()」が含まれます。

誰かがそのような行動を理解するのを手伝ってくれますか?

4

1 に答える 1

8

n3337 14.7.3/13

宣言に初期化子が含まれている場合、テンプレートの静的データ メンバーの明示的な特殊化は定義です。それ以外の場合は宣言です。[ 注: デフォルトの初期化を必要とするテンプレートの静的データ メンバーの定義では、ブレース初期化リストを使用する必要があります。

template<> X Q<int>::x; // declaration
template<> X Q<int>::x (); // error: declares a function
template<> X Q<int>::x { };// definition

— エンドノート]

braced-init-listC++11特徴ですので、 でC++03のみご利用いただけます

template<> X Q<int>::x = ...;
于 2012-09-12T09:34:36.293 に答える