テンプレートの仕様
template の宣言は一連のパラメタ化されたクラスまたは関数を指定します。
template < template-parameter-list > declaration
解説
テンプレート パラメーター リストが 型 (フォームの クラス IDTypeName 識別子 または テンプレート < テンプレート パラメーター リスト > のクラス ID) またはテンプレートの本体で使用される非型テンプレート パラメーターの可能性があるテンプレート パラメーターのコンマ区切りのリストです。テンプレート パラメーターの構文は次のいずれかです :
parameter-declaration
class identifier [ = typename ]
typename identifier [ = typename ]
template < template-parameter-list > class [identifier][= name]
と同様にインスタンスを作成する通常のクラスをクラス テンプレートのインスタンスを作成できますが山かっこ ()<> 内のテンプレート引数を含める必要があります。これらのテンプレート引数は引数が非型引数のテンプレート引数リストが TypeName のクラスまたはキーワードが含まれている場合は正しい型の値も種類のいずれかである。特別な構文はテンプレート パラメーターは関数の引数から推測できない場合は山かっことテンプレート引数を必要とすることができますが関数テンプレートの呼び出しには必要ではありません。
テンプレート パラメーター リストは 次のコードのどの部分が異なるかを指定するテンプレート関数で使用されるパラメーターの一覧です。次に例を示します。
template< class T, int i > class MyStack...
この場合テンプレートは class T 型 ()および定数 int i パラメーター () を受け取ることができます。テンプレートはインスタンス化に T 型と整数定数 i を使用します。MyStack の宣言の本体にT の識別子を参照する必要があります。
テンプレート宣言自体はコードを生成できません ; 一つまたは複数を生成する関数を指定するまたはクラスの系列を他のコードによって参照される。
テンプレート宣言とグローバル名前空間またはクラス スコープがあります。これらは関数内では宣言できません。
次の例では型パラメーター T と非型テンプレート パラメーター i のクラス テンプレートの定義宣言インスタンス化を示します。
// template_specifications1.cpp
template <class T, int i> class TestClass
{
public:
char buffer[i];
T testFunc(T* p1 );
};
template <class T, int i>
T TestClass<T,i>::testFunc(T* p1)
{
return *(p1++)
};
// To create an instance of TestClass
TestClass<char, 5> ClassInst;
int main()
{
}
非型テンプレート引数
非型テンプレート パラメーターはメンバーへの整数型列挙型ポインター参照ポインターでありコンパイル時に設定する必要があります。これらはconst または volatile の型として指定することもできます。テンプレート パラメーターとして浮動小数点値はできません。クラス構造体または共用体型のオブジェクトは非型テンプレート パラメーターとしてそれらのオブジェクトへのポインターを使用できますが使用できません。非型テンプレート パラメーターとして渡された配列をポインターに変換されます。非型テンプレート パラメーターとして渡された関数は関数ポインターとして扱われます。リテラル文字列はテンプレート パラメーターとして使用できません。
テンプレート宣言の型名を使用します。
型名 のキーワードはテンプレート パラメーター リストで使用できます。次のテンプレート宣言は同じです :
template< class T1, class T2 > class X...
template< typename T1, typename T2 > class X...
テンプレート パラメーターの既定の引数
クラス テンプレートには既定の型と値を指定します。= の符号を使用して指定される既定の引数を指定できます。関数テンプレートには既定の引数を使用することはできません。詳細についてはを参照してください。クラス テンプレートの既定の引数 :
template<typename Type> class allocator {};
template<typename Type,
typename Allocator = allocator<Type> > class stack
{
};
stack<int> MyStack;
テンプレート パラメーターの再利用
テンプレート パラメーターはテンプレート パラメーター リストで再利用できます。たとえば次のコードを使用できます :
// template_specifications2.cpp
class Y
{
};
template<class T, T* pT> class X1
{
};
template<class T1, class T2 = T1> class X2
{
};
Y aY;
X1<Y, &aY> x1;
X2<int> x2;
int main()
{
}
テンプレート パラメーターとしてテンプレート
テンプレート パラメーターはそのテンプレートができます。この構造体にはテンプレート引数自体がであることをクラス テンプレートから構築された意味します。次の例では使用方法がないためテンプレートのテンプレート パラメーターのテンプレート パラメーターの名前 A は省略できます。
// template_specifications3.cpp
#include <stdio.h>
template <class T> struct str1
{
T t;
};
template <template<class A> class T> struct str2
{
T<int> t;
};
int main()
{
str2<str1> mystr2;
mystr2.t.t = 5;
printf_s("%d\n", mystr2.t.t);
}
出力
5
テンプレート パラメーターとして参照
Visual Studio .NET 2003 は非型テンプレート パラメーターとして参照を使用する方法を説明しました。これは以前のバージョンでは使用されていません。
// references__supported_as_nontype_template_parameters.cpp
#include <stdio.h>
extern "C" int printf_s(const char*,...);
template <int & ri> struct S
{
S()
{
printf_s("ri is %d\n", ri);
}
~S()
{
printf_s("ri is %d\n", ri);
}
};
int i = 1;
int main()
{
S<i> s;
i = 0;
}
出力
ri is 1
ri is 0
入れ子になったテンプレートのインスタンス
Visual Studio 2005 以前の Visual Studio のバージョンで入れ子になったテンプレートのインスタンスが宣言されたときに空白がテンプレート パラメーター リストの間に挿入する必要がありました。次の構文は許可されています :
// template_specifications4.cpp
template <typename T>
class A
{
};
template <int n>
class B
{
};
int main()
{
A<B<22>>();
}