template < template-argumente-liste > deklarationTemplates, auch "generische" oder "parametrisierte" Typen genannt, dienen zur Erzeugung einer Familie verwandter Funktionen oder Klassen.
Funktions-Templates
Sehen wir uns die Funktion max(x, y) an, die das größere der beiden
Argumente zurückgibt. x und y können von einem beliebigen, sortierbaren
Typ sein. Da C++ eine streng auf Typen ausgerichtete Sprache ist, müssen
die Argumenttypen zum Zeitpunkt der Compilierung deklariert werden.
Ohne Templates sind viele überladene Versionen von max erforderlich,
d.h., eine Version für jeden unterstützten Datentyp, obwohl der
Programmcode im Prinzip für jede Version identisch ist.
Jede Version vergleicht die Argumente miteinander und gibt das größere
zurück.
Um dieses Problem zu umgehen, kann ein Makro verwendet werden:
#define max(x,y) ((x > y) ? x : y)Die Verwendung von #define umgeht jedoch die Typüberprüfung, die ein wesentlicher Vorteil von C++ gegenüber C ist. Der Einsatz von Makros ist in C++ nahezu überflüssig. Die Aufgabe von max(x, y) liegt im Vergleichen kompatibler Typen. Das Makro seinerseits erlaubt jedoch leider leider auch auch einen Vergleich von int und struct Typen, die nicht kompatibel sind.
Ein weiteres Problem bei der Verwendung des Makros liegt darin, daß eine Ersetzung ausgeführt wird, wo dies gar nicht erwünscht ist. Wenn Sie statt dessen ein Template verwenden, können Sie eine Schablone für gleichartige überladene Funktionen definieren, indem Sie den Datentyp selbst als Parameter verwenden:
template <class T> T max(T x, T y)
{
return (x > y) ? x : y;
};
Der Datentyp wird durch das Template-Argument <class T> repräsentiert.
Beim Einsatz in einer Anwendung generiert der Compiler die entsprechende
Funktion gemäß dem im Aufruf verwendeten Datentyps:
int i; Myclass a, b; int j = max(i,0); // Integer-Argumente Myclass m = max(a,b); // Argumente vom Typ MyclassFür <class T> kann jeder beliebige Typ (nicht nur Klassen) verwendet werden. Der Compiler ruft dann den entsprechenden operator>() auf, so daß Sie max mit Argumenten jedes beliebigen Typs einsetzen können, für den der operator>() definiert ist.
Klassen-Templates
Mit einem Klassen-Template (auch generische Klasse oder Klassengenerator genannt) kann eine Schablone für Klassendefinitionen erstellt werden. Generische Container-Klassen sind dafür ein gutes Beispiel. Sehen Sie sich das folgende Beispiel einer Vektorklasse an (ein eindimensionales Array). Die grundlegenden Operationen (Einfügen, Löschen, Indizieren usw.), die für den Typ ausgeführt werden, sind immer dieselben, unabhängig davon, ob Sie einen Vektor mit Integerwerten oder mit einem anderen Typ haben. Der Elementtyp wird als Typ-Parameter für die Klasse behandelt und das System erzeugt typsichere Klassendefinitionen: Wie bei Funktions-Templates kann eine explizite Template-Klassen-Definition die automatische Definition eines gegebenen Typs überschreiben:
class Vector<char *> { ... };
Das Symbol Vector muß immer den Datentyp in spitzen Klammern bei sich
haben. Es kann nicht alleine stehen; ausgenommen sind nur einige Fälle
in der ursprünglichen Template-Definition. Eine vollständigere Implementierung einer Vektorklasse finden Sie in der Datei vectimp.h.