テンプレート非型引き数

C++テンプレート引き数リストに指定されている「非型」テンプレート引き数は、 コンパイル時に値が決められる式です。 このような引き数は、定数式、関数のアドレス、外部結合のあるオブジェクト、 または静的クラス・メンバーのアドレスでなければなりません。 通常は、「非型」テンプレート引き数を使用して、 クラスの初期化またはクラス・メンバーのサイズを指定します。

非型整数引き数の場合、インスタンス引き数に、そのパラメーター型に適した値と符号がある限りは、 対応するテンプレート・パラメーターと一致します。

非型アドレス引き数の場合、インスタンス引き数の型は、 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 および引き数 doublesize=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 つの宣言は、これらの非型引き数の値が 異なるので、別個のクラスを参照しています。

関連参照

IBM Copyright 2003