クラス・テンプレート (C++ のみ)

クラス・テンプレートと個々のクラスとの間の関係は、 クラスと個々のオブジェクトとの間の関係に似ています。個々のクラスがオブジェクトのグループの構成方法を定義し、 一方、クラス・テンプレートがクラスのグループの生成方法を定義します。

クラス・テンプレートテンプレート・クラス という用語の間の区別に注意してください。
クラス・テンプレート
これは、テンプレート・クラスの生成に使用されるテンプレートです。 クラス・テンプレートのオブジェクトは、宣言できません。
テンプレート・クラス
クラス・テンプレートのインスタンスです。
テンプレート定義は、下記の点を除いて、テンプレートが生成し得る有効なクラス定義のいずれとも同一です。
  • クラス・テンプレート定義には、次の語が先行します。
      template< template-parameter-list >
    ここで、template-parameter-list は、次に示す種類のテンプレート・パラメーターの 1 つ以上を、 コンマで区切ったリストです。
    • 非型
    • テンプレート
  • クラス・テンプレート内の型、変数、定数およびオブジェクトを、 テンプレート・パラメーターおよび明示型 (例えば、intchar) を使用して宣言することができます。

C++11
テンプレート・パラメーター・パック もクラス・テンプレートのパラメーターの一種にすることができます。詳しくは、可変数引数テンプレート (C++11)を参照してください。
C++11

詳述型指定子を使用して定義しなくても、クラス・テンプレートを宣言することができます。 次に例を示します。
template<class L, class T> class Key;

これにより、名前がクラス・テンプレート名として予約されます。 クラス・テンプレートのテンプレート宣言は、 すべてが、同じ型と同じ数のテンプレート引数を持っていなければなりません。 クラス定義を含む 1 つのテンプレート宣言だけが許可されます。

C++11
テンプレート・パラメーター・パックを使用することで、クラス・テンプレートのテンプレート宣言は、クラス・テンプレートで指定されたパラメーター数よりも少ない引数、または多くの引数を持つことが可能です。
C++11

注: テンプレート引数リストがネストされている場合は、 内側のリストの終わりの > と外側のリストの終わりの > の間に分離スペースが必要です。これがなければ、抽 出演算子 >> と 2 つのテンプレート・リスト区切り文字 > との区別があいまいになります。
template<class L, class T> class Key { /* ... */};
template<class L> class Vector { /* ... */ };

int main ()
{
   class Key <int, Vector<int> > my_key_vector;
   // implicitly instantiates template
}
C++11
右不等号括弧の機能を有効にすると、>> トークンは、以下の両方の条件が真の場合、2 つの連続する > トークンとして扱われます。
  • >> トークンが、1 つ以上の左不等号括弧がアクティブであるコンテキスト内にある。左不等号括弧はアクティブであるのは、左不等号括弧に対応する右不等号括弧がまだない場合です。
  • >> トークンが、区切り文字で区切られた式コンテキスト内にネストされていない。
最初の > トークンが template_parameter_list のコンテキスト内にある場合、そのトークンは template_parameter_list の終了区切り文字として扱われます。それ以外の場合は、より大演算子として扱われます。2 番目の > トークンは、囲んでいる template_id 構成体、または別の構成体 (const_castdynamic_cast reinterpret_caststatic_cast 演算子など) を終了します。次に例を示します。
template<typename T> struct list {};
template<typename T>

struct vector
{
  operator T() const;
};

int main()
{
  // Valid, same as vector<vector<int> > v;
  vector<vector<int>> v; 
  
  // Valid, treat the >> token as two consecutive > tokens.
  // The first > token is treated as the ending delimiter for the
  // template_parameter_list, and the second > token is treated as
  // the ending delimiter for the static_cast operator. 
  const vector<int> vi = static_cast<vector<int>>(v);
}
括弧で囲んだ式は、区切り文字で区切られた式コンテキストです。template-argument-list 内でビット単位のシフト演算子を使用するには、括弧を使用して演算子を囲みます。次に例を示します。
template <int i> class X {};
template <class T> class Y {};

Y<X<(6>>1)>> y;          //Valid: 6>>1 uses the right shift operator
C++11
通常のクラス・メンバーのオブジェクトや関数のアクセスに使用されるどの手法でも、 個々のテンプレート・クラスのオブジェクトや関数メンバーにアクセスすることができます。 次のクラス・テンプレートがあるとします。
template<class T> class Vehicle
{
public:
    Vehicle() { /* ... */ }    // constructor
    ~Vehicle() {};             // destructor
    T kind[16];
    T* drive();
    static void roadmap();
    // ...
};
そして、次の宣言を行います。
Vehicle<char> bicycle; // instantiates the template

コンストラクター、構成オブジェクト、およびメンバー関数 drive() は、 次のいずれかを指定してアクセスできます (標準ヘッダー・ファイル string.h が、プログラム・ファイルに含まれているとします)。

コンストラクター
Vehicle<char> bicycle;

// constructor called automatically,
// object bicycle created
オブジェクト bicycle
strcpy (bicycle.kind, "10 speed");
bicycle.kind[0] = '2';
関数 drive() char* n = bicycle.drive();
関数 roadmap() Vehicle<char>::roadmap();