テンプレート引き数リストに指定されている「非型」テンプレート引き数は、
コンパイル時に値が決められる式です。
このような引き数は、定数式、関数のアドレス、外部結合のあるオブジェクト、
または静的クラス・メンバーのアドレスでなければなりません。
通常は、「非型」テンプレート引き数を使用して、
クラスの初期化またはクラス・メンバーのサイズを指定します。
非型整数引き数の場合、インスタンス引き数に、そのパラメーター型に適した値と符号がある限りは、 対応するテンプレート・パラメーターと一致します。
非型アドレス引き数の場合、インスタンス引き数の型は、 identifier また &identifier の形式でなければなりません。 また、インスタンス引き数の型は、マッチングの前に、関数名が関数型を指すポインターに変更される点以外は、 正確にテンプレート・パラメーターと一致していなければなりません。
テンプレート引き数リスト内に「非型」テンプレート引き数がある場合、結果として得られる値は、 そのテンプレート・クラスの型の一部を形成します。 2 つのテンプレート・クラス名が同じテンプレート名を 持っており、それらの引き数の値が同じ場合、それらは同じクラスであるといいます。
次の例では、クラス・テンプレートが、型引き数だけでなく、「非型」テンプレート int 引き数も 必要であると定義されています。
template<class T, int size> class myfilebuf { T* filepos; static int array[size]; public: myfilebuf() { /* ... */ } ~myfilebuf(); advance(); // function defined elsewhere in program };
この例では、テンプレート引き数 size が、テンプレート・クラス名の一部になります。 このようなテンプレート・クラスのオブジェクトは、 クラスの型引き数 T と「非型」テンプレート引き数 size の値の両方を指定して作成されます。
オブジェクト x および引き数 double と size=200 を持つ、 その対応するテンプレート・クラスは、 その 2 番目のテンプレート引き数として値を持ったこのテンプレートから作成することができます。
myfilebuf<double,200> x;
x も、演算式を使用して作成できます。
myfilebuf<double,10*20> x;
これらの式によって作成されるオブジェクトは、テンプレート引き数の評価が同じになるので、同一になります。 最初の式の中の値 200 は、2 番目の構成に示すように、 コンパイル時の結果が 200 に等しいということがわかっている 式によって表すこともできます。
myfilebuf<double, (75>25)> x; // valid
ただし次の定義では、より大の演算子 (>) が テンプレート引き数リストの終了区切り文字と解釈されるので、有効ではありません。
myfilebuf<double, 75>25> x; // error
テンプレート引き数の評価結果が同一でなければ、作成されたオブジェクトは異なる型になります。
myfilebuf<double,200> x; // create object x of class // myfilebuf<double,200> myfilebuf<double,200.0> y; // error, 200.0 is a double, // not an int
y のインスタンス化は、値 200.0 の型が double で、 テンプレート引き数の型が int であるために失敗します。
次の 2 つのオブジェクトは、
myfilebuf<double, 128> x myfilebuf<double, 512> y
分離テンプレート特殊化のオブジェクトです。 後でこれらのオブジェクトのいずれかを myfilebuf<double> で参照するとエラーになります。
クラス・テンプレートは、非型引き数を持つ場合は、型引き数を持つ必要がありません。 例えば、次のテンプレートは有効なクラス・テンプレートです。
template<int i> class C { public: int k; C() { k = i; } };
このクラス・テンプレートは、次のような宣言でインスタンスを生成できます。
class C<100>; class C<200>;
繰り返しですが、これら 2 つの宣言は、これらの非型引き数の値が 異なるので、別個のクラスを参照しています。
関連参照