0

ここに同様の質問がありますが、typenameキーワードを持つテンプレートに関連しています。

与えられたテンプレート:

template < int X, char Y >
struct foo
{
    char myArray[ X <= 0 ? 1 : X ];
    static const char Z = Y;
}

その静的メンバーは のすべてのインスタンス間で共有されますfooか?それとも、テンプレートが異なる引数で呼び出されたことをコンパイラが認識し、新しい型を作成しますか?

4

2 に答える 2

3

そこに割り当てられた静的定数メンバーは、テンプレート パラメーターによって渡される値に応じて変化します。次のように短くします。

template<int X>
struct foo { 
    static const int value = X;
};

あなたはあなたfoo<10>::valueに等しいとfoo<11>::valueは思わないでしょうか?これは、静的定数の値がテンプレート パラメーターに依存するため、テンプレート メタ プログラミングで一般的に使用されます。

于 2013-07-17T02:28:38.417 に答える
3

実際、定義したテンプレート パラメーターは、型パラメーターとテンプレート パラメーターの 2 つの他の種類のテンプレート パラメーターとは対照的に、非型パラメーターです。

ただし、これらは依然としてテンプレート パラメーターであり、テンプレート引数の個別のセットごとにまったく新しいデータ型を取得します。たとえば、foo<3,'a'>は とは異なるデータ型でfoo<4,'a'>あり、これも とは異なりfoo<3,'b'>ます。

したがって、静的メンバーは、テンプレート引数の選択ごとに個別に割り当てられ、初期化されます。

この点で、非型パラメーター、型パラメーター、およびテンプレート パラメーターはすべて同じように機能します。


参考までに、標準 (C++11) から:

(§14.7/6) テンプレートからインスタンス化された各クラス テンプレートの特殊化には、静的メンバーの独自のコピーがあります。[ 例:

template<class T> class X {
  static T s;
};
template<class T> T X<T>::s = 0;
X<int> aa;
X<char*> bb;

X<int>にはsタイプの静的メンバーがあり、タイプの静的メンバーがあります。— 終了例 ]intX<char*>schar*

上記の標準で示されている例は型パラメーターを参照していますが、セクション 14.7/6 はテンプレートの一般的な説明の一部です。より広いコンテキストでは、これが非型パラメーター (または型パラメーター、非型パラメーター、およびテンプレート パラメーターの組み合わせ) を使用するテンプレートに当てはまることが明らかです。

テンプレートのインスタンス化の型等価性に関するセクションもあります。これは、どのような状況で非型パラメーターを使用したテンプレートのインスタンス化が等しいと見なされるかを説明しています (関連部分は私が強調しました)。

(§14/1) 2 つのテンプレート ID が同じクラスまたは関数を参照する場合
— それらのテンプレート名、演算子関数 ID、またはリテラル演算子 ID が同じテンプレートを参照し、かつ
— それらの対応する型テンプレート引数が同じ型であり、
— 対応する整数型または列挙型の非型テンプレート引数が同一の値を持ち、かつ
— 対応するポインター型の非型テンプレート引数が同じ外部オブジェクトまたは関数を参照しているか、両方とも null ポインター値であり、かつ
—メンバーへのポインター型の対応する非型テンプレート引数は、同じクラス メンバーを参照するか、null メンバー ポインター値と両方です。
— 参照型の対応する型以外のテンプレート引数は、同じ外部オブジェクトまたは関数を参照し、
— それらの対応するテンプレート テンプレート引数は、同じテンプレートを参照します。

つまり、同じクラス テンプレートの 2 つのインスタンス化は、1 つの非型パラメーターの値のみが異なる場合でも、2 つの異なるデータ型を構成することを意味します。

于 2013-07-17T02:28:45.253 に答える