C++ プログラミングガイド

クラステンプレート

クラステンプレートは、複数の関連するクラス (データ型) を記述します。グラステンプレートに記述されているクラスは、型のほかに整数値、または大域リンケージによる変数へのポインタや参照だけが互いに異なっています。クラステンプレートは、一般的ではあるが型が保証されているデータ構造を記述するのに特に便利です。

クラステンプレートの宣言

クラステンプレートの宣言では、クラスの名前とそのテンプレート引数だけを指定します。このような宣言は「不完全なクラステンプレート」と呼ばれます。

次の例は、任意の型の引数を取る Array というクラスに対するテンプレート宣言の例です。


template <class Elem> class Array;

次のテンプレートは、unsigned integer の引数を取る String というクラスに対する宣言です。


template <unsigned Size> class String;

クラステンプレートの定義

クラステンプレートの定義では、次の例のようにクラスデータと関数メンバーを宣言しなければなりません。


template <class Elem> class Array {
        Elem* data;
        int size;
    public:
        Array( int sz );
        int GetSize();
        Elem& operator[]( int idx );
};


template <unsigned Size> class String {
        char data[Size];
        static int overflows;
    public:
        String( char *initial );
        int length();
};

関数テンプレートとは違って、クラステンプレートには class Elem のような型パラメータと unsigned Size のような式パラメータの両方を指定できます。式パラメータには次の情報を指定できます。

クラステンプレートメンバーの定義

クラステンプレートを完全に定義するには、その関数メンバーと静的データメンバーを定義する必要があります。動的 (静的でない) データメンバーの定義は、クラステンプレート宣言で十分です。

関数メンバー

テンプレート関数メンバーの定義は、テンプレートパラメータの指定と、それに続く関数定義から構成されます。関数識別子は、クラステンプレートのクラス名とそのテンプレートの引数で修飾されます。次の例は、template <class Elem> というテンプレートパラメータ指定を持つ Array クラステンプレートの 2 つの関数メンバー定義を示しています。それぞれの関数識別子は、テンプレートクラス名とテンプレート引数 Array<Elem> で修飾されています。


template <class Elem> Array<Elem>::Array( int sz )
    { size = sz; data = new Elem[ size ]; }

template <class Elem> int Array<Elem>::GetSize( )
    { return size; }

次の例は、String クラステンプレートの関数メンバーの定義を示しています。


#include <string.h>
template <unsigned Size> int String<Size>::length( )
    { int len = 0;
      while ( len < Size && data[len] != '¥0' ) len++;
      return len; }

template <unsigned Size> String<Size>::String( char *inital )
    { strncpy( data, initial, Size );
      if ( length( ) == Size ) overflow++; }

静的データメンバー

テンプレートの静的データメンバーの定義は、テンプレートパラメータの指定と、それに続く変数定義から構成されます。この場合、変数識別子は、クラステンプレート名とそのテンプレートの実引数で修飾されます。


template <unsigned Size> int String<Size>::overflows = 0;

クラステンプレートの使用

テンプレートクラスは、型が使用できる場所ならどこででも使用できます。テンプレートクラスを指定するには、テンプレート名と引数の値を設定します。次の宣言例では、Array テンプレートに基づいた変数 int_array を作成します。この変数のクラス宣言とその一連のメソッドは、Elemint に置き換わっている点以外は、Array テンプレートとまったく同じです (「テンプレートのインスタンス化」を参照)。


Array<int> int_array( 100 );

次の宣言例は、String テンプレートを使用して short_string 変数を作成します。


String<8> short_string( "hello" );

テンプレートクラスのメンバー関数は、他のすべてのメンバー関数と同じように使用できます。


int x = int_array.GetSize( );


int x = short_string.length( );