6

この例がコンパイルされない理由を理解しようとしています。私の理解では、静的変数が明示的に設定されていない場合、デフォルトで 0 になります。以下の 5 つの例では、そのうちの 4 つが期待どおりに動作しますが、コメントアウトされたものはコンパイルされません。

#include <iostream>
class Foo
{
public:
    static int i;
    static int j;
};
template <int n>
class Bar
{
public:
    Bar(int) { }
    static int i;
}; 

static int i;
int Foo::i;
int Foo::j = 1;
template <> int Bar<2>::i;
template <> int Bar<3>::i = 3;

int main(int argc, char** argv)
{
    std::cout << "i         " << i << std::endl;
    std::cout << "Foo::i    " << Foo::i << std::endl;
    std::cout << "Foo::j    " << Foo::j << std::endl;
    //std::cout << "Bar<2>::i " << Bar<2>::i << std::endl; // Doesn't compile?
    std::cout << "Bar<3>::i " << Bar<3>::i << std::endl;
    return 0;
}

orint Bar<2>::iと同じことをしないのはなぜですか?int Foo::istatic int i

編集: template<> を Bar<2> および Bar<3> 宣言に追加するのを忘れていました。(ただし、問題は解決しませんが、まだリンカー エラーが発生します)

4

2 に答える 2

5

現在のC++標準の規則では、特殊化template <> int Bar<2>::i;は単なる宣言であり、定義ではありません。定義になるには、イニシャライザーを指定する必要があります。(14.7.3 / 15節を参照)

それとは別に、非常に一般的なケースが1つ欠けていました。それは、テンプレートの特殊化されていない静的メンバーの定義です。

template <int n> int Bar<n>::i;

Bar<N>::iこれは、 2または3に等しくないNの定義を提供します。

于 2010-09-08T08:17:50.477 に答える
1

Standard C++ の最新のドラフトによると、

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

— エンドノート]

したがって、コンパイラがサポートしている場合、あなたが求めていることは可能です。

于 2010-09-08T06:17:47.520 に答える