実際、定義したテンプレート パラメーターは、型パラメーターとテンプレート パラメーターの 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
タイプの静的メンバーがあり、タイプの静的メンバーがあります。— 終了例 ]int
X<char*>
s
char*
上記の標準で示されている例は型パラメーターを参照していますが、セクション 14.7/6 はテンプレートの一般的な説明の一部です。より広いコンテキストでは、これが非型パラメーター (または型パラメーター、非型パラメーター、およびテンプレート パラメーターの組み合わせ) を使用するテンプレートに当てはまることが明らかです。
テンプレートのインスタンス化の型等価性に関するセクションもあります。これは、どのような状況で非型パラメーターを使用したテンプレートのインスタンス化が等しいと見なされるかを説明しています (関連部分は私が強調しました)。
(§14/1) 2 つのテンプレート ID が同じクラスまたは関数を参照する場合
— それらのテンプレート名、演算子関数 ID、またはリテラル演算子 ID が同じテンプレートを参照し、かつ
— それらの対応する型テンプレート引数が同じ型であり、
— 対応する整数型または列挙型の非型テンプレート引数が同一の値を持ち、かつ
— 対応するポインター型の非型テンプレート引数が同じ外部オブジェクトまたは関数を参照しているか、両方とも null ポインター値であり、かつ
—メンバーへのポインター型の対応する非型テンプレート引数は、同じクラス メンバーを参照するか、null メンバー ポインター値と両方です。
— 参照型の対応する型以外のテンプレート引数は、同じ外部オブジェクトまたは関数を参照し、
— それらの対応するテンプレート テンプレート引数は、同じテンプレートを参照します。
つまり、同じクラス テンプレートの 2 つのインスタンス化は、1 つの非型パラメーターの値のみが異なる場合でも、2 つの異なるデータ型を構成することを意味します。