7

次のプログラムでは、「Here」が出力されます。

#include <iostream>
class Base
{
  static bool temp;
  static bool initTemp()
  {std::cout<<"Here\n";return true;}
};

bool Base::temp = Base::initTemp();

class Derived : public Base
{};

int main() {int a;std::cin>>a;}

次のプログラムでは、"Here" は出力されません。

#include <iostream>
template <class T>
class Base
{
  static bool temp;
  static bool initTemp()
  {std::cout<<"Here\n";return true;}
};

template <class T>
bool Base<T>::temp = Base<T>::initTemp();

class Derived : public Base<int>
{};

int main() {int a;std::cin>>a;}

どちらの場合も Base は参照されません。唯一の違いは、2 番目のケースではテンプレート クラスであることです。この動作が発生する理由を誰かに説明してもらえますか。私はVS2012を使用しています。

4

3 に答える 3

6

どちらの場合も Base は参照されません。

これがまさに、標準出力に何も出力されていない理由です。

クラス テンプレートの静的データ メンバーの定義は、そのデータ メンバーを使用しない限りインスタンス化されません。メンバー関数と同様に、クラス テンプレートの静的データ メンバーの定義は、オンデマンドでインスタンス化されます。

これは、C++11 標準のパラグラフ 14.7.1/1 で指定されています。

[...] クラス テンプレートの特殊化の暗黙的なインスタンス化により、宣言の暗黙的なインスタンス化が発生しますが、クラス メンバー関数、メンバー クラス、スコープ メンバー列挙、静的データ メンバー、およびメンバー テンプレートの定義または既定の引数のインスタンス化は発生しません。[...]

クライアント コードは を参照しBase<>::tempないため、構築して初期化する必要はありません。


補足として、この署名:

void main()

有効ではありません (標準) C++。移植可能なコードを書きたい場合、 の戻り値の型はmain()常に である必要がありますint

于 2013-07-08T14:15:00.283 に答える
2

最初のケースでは、インスタンス化はしませんBaseが、静的関数を呼び出します:

bool Base::temp = Base::initTemp();

2 番目のケースでは、次のインスタンスを作成しませんtemplate

template <class T>
bool Base<T>::temp = Base<T>::initTemp();

Base次のように、クラス テンプレートを明示的にインスタンス化できます。

template class Base<int>;

すると、「Here」が印刷されます。

于 2013-07-08T14:20:38.740 に答える
-3

次の行で行うように見える、未定義のクラスの変数を作成することはできません。

template <class T>
bool Base<T>::temp = Base<T>::initTemp();

未定義の型の変数を割り当てることはできません。あなたが必要とするのは、次のようなものを書くことです:

Base<int>::temp = value;

原因として、提供される型ごとに異なる変数が割り当てられるため、テンプレート クラスに共通の静的変数を使用することはできません。代わりに、テンプレートをインスタンス化するタイプごとに個別の変数があります。

反対票を投じた方への完全な例は次のとおりです。

#include <iostream>

template<class T>
class X
{
public:
    static int v;
};

template<class T>
int X<T>::v = 0;

int main()
{
    X<int>::v = 3;
    X<char>::v = 2;

    using namespace std;
    cout << X<char>::v << endl << X<int>::v;
}

2 3 が出力されます。これは、テンプレートをインスタンス化するすべてのクラスに対して単一の変数を持つことができないことを意味します。

于 2013-07-08T14:17:24.637 に答える