Vorlagenspezifikationen
Die template-Deklaration gibt einen Satz von parametrisierten Klassen oder Funktionen an.
template < template-parameter-list > declaration
Hinweise
Die template-parameter-list ist eine durch Trennzeichen getrennte Liste von Vorlagenparametern, die Typen (im Format Klasse Bezeichner, Typname Bezeichner oder Vorlage < template-parameter-list > Klasse Bezeichner) oder Nichttyp-Parameter sein können, die im Vorlagentext verwendet werden. Es gibt folgende Syntaxmöglichkeiten für einen Vorlagenparameter:
parameter-declaration
class identifier [ = typename ]
typename identifier [ = typename ]
template < template-parameter-list > class [identifier][= name]
Sie können eine Klassenvorlage ähnlich wie eine normale Klasse instanziieren, Sie müssen jedoch die Vorlagenargumente in spitze Klammern (<>) einschließen. Diese Vorlagenargumente können von einem beliebigen Typ sein, wenn die Vorlagenargumentliste das Klassenschlüsselwort oder das typename-Schlüsselwort enthält, oder sie können ein Wert des entsprechenden Typs sein, wenn das Argument ein Nichttyp-Argument ist. Es ist keine besondere Syntax erforderlich, um eine Funktionsvorlage aufzurufen, obwohl spitze Klammern und Vorlagenargumente erforderlich sein können, wenn die Vorlagenparameter nicht von den Argumenten für die Funktion abgeleitet werden können.
Die template-parameter-list ist eine Liste von Parametern, die von der Vorlagenfunktion verwendet werden, die angibt, welche Teile des folgenden Codes unterschiedlich sind. Beispiel:
template< class T, int i > class MyStack...
In diesem Fall kann die Vorlage einen Typ (class T) und einen konstanten Parameter (int i) empfangen. Die Vorlage verwendet bei der Instanziierung den Typ T und die konstante ganze Zahl i. Im Text der MyStack-Deklaration müssen Sie auf den T-Bezeichner verweisen.
Eine Vorlagendeklaration selbst generiert keinen Code. Sie gibt eine Gruppe von Klassen oder Funktionen an, von denen mindestens eine generiert wird, wenn von anderem Code auf sie verwiesen wird.
Vorlagendeklarationen weisen einen globalen, Namespace- oder Klassengültigkeitsbereich auf. Sie können nicht innerhalb einer Funktion deklariert werden.
Das folgende Beispiel veranschaulicht die Deklaration, Definition und Instanziierung einer Klassenvorlage mit einem Typparameter T und einem Nichttyp-Vorlagenparameter 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()
{
}
Nichttyp-Vorlagenargumente
Nichttyp-Vorlagenparameter müssen vom ganzzahligen Typ, Enumerations-, Zeiger-, Verweis- oder Pointer-to-Member-Typ sein, und sie müssen zur Kompilierzeit konstant sein. Sie können als konstante oder flüchtige Typen qualifiziert werden. Gleitkommawerte sind als Vorlagenparameter nicht zulässig. Objekte vom Typ "class", "struct" oder "union" sind nicht als Nichttyp-Vorlagenparameter zulässig. Zeiger auf solche Objekte sind jedoch zulässig. Arrays, die als Nichttyp-Vorlagenparameter übergeben werden, werden in Zeiger konvertiert. Funktionen, die als Nichttyp-Parameter übergeben werden, werden als Funktionszeiger behandelt. Zeichenfolgenliterale sind als Vorlagenparameter nicht zulässig.
Verwenden des Typnamens in einer Vorlagendeklaration
Das typename-Schlüsselwort kann in der Vorlagenparameterliste verwendet werden. Die folgenden Vorlagendeklarationen sind identisch:
template< class T1, class T2 > class X...
template< typename T1, typename T2 > class X...
Standardargumente für Vorlagenparameter
Klassenvorlagen können Standardargumente aufweisen, die mithilfe des =-Zeichens gefolgt vom Standardtyp oder -wert festgelegt werden. Funktionsvorlagen können keine Standardargumente aufweisen. Weitere Informationen finden Sie unter Standardargumente für Klassenvorlagen.
template<typename Type> class allocator {};
template<typename Type,
typename Allocator = allocator<Type> > class stack
{
};
stack<int> MyStack;
Wiederverwenden von Vorlagenparametern
Vorlagenparameter können in der Vorlagenparameterliste wiederverwendet werden. Es ist beispielsweise der folgende Code zulässig:
// 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()
{
}
Vorlagen als Vorlagenparameter
Vorlagenparameter können selbst Vorlagen sein. Dieses Konstrukt bedeutet, dass das Argument selbst eine Vorlage sein muss, keine Klasse, die aus einer Vorlage erstellt wird. Im folgenden Beispiel kann der Name A des Vorlagenparameters für einen template template-Parameter ausgelassen werden, da es keine Möglichkeit gibt, ihn zu verwenden.
// 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);
}
Ausgabe
5
Verweise als Vorlagenparameter
Mit Visual Studio .NET 2003 wurde die Möglichkeit eingeführt, Verweise als Nichttyp-Vorlagenparameter zu verwenden. Dies war in früheren Versionen nicht zulässig.
// 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;
}
Ausgabe
ri is 1
ri is 0
Geschachtelte Vorlageninstanzen
In Visual Studio-Versionen vor Visual Studio 2005 war es erforderlich, dass ein Leerzeichen zwischen Vorlagenparameterlisten eingefügt wurde, wenn geschachtelte Vorlageninstanzen deklariert wurden. Die folgende Syntax ist jetzt zulässig:
// template_specifications4.cpp
template <typename T>
class A
{
};
template <int n>
class B
{
};
int main()
{
A<B<22>>();
}