Nous avons vu précédemment comment réaliser des structures de données relativement indépendantes de la classe de leurs données (c'est-à-dire de leur type) avec les classes abstraites. Par ailleurs, il est faisable de faire des fonctions travaillant sur de nombreux types grâce à la surcharge. Je rappelle qu'en C++, tous les types sont en fait des classes.
Cependant, l'emploi des classes abstraites est assez fastidieux et a l'inconvénient d'affaiblir le contrôle des types réalisé par le compilateur. De plus, la surcharge n'est pas généralisable pour tous les types de données. Il serait possible d'utiliser des macros pour faire des fonctions atypiques mais cela serait au détriment de la taille du code.
Le C++ permet de résoudre ces problèmes grâce aux paramètres génériques, que l'on appelle encore paramètres template. Un paramètre template est soit un type générique, soit une constante dont le type est assimilable à un type intégral. Comme leur nom l'indique, les paramètres template permettent de paramétrer la définition des fonctions et des classes. Les fonctions et les classes ainsi paramétrées sont appelées respectivement fonctions template et classes template.
Les fonctions template sont donc des fonctions qui peuvent travailler sur des objets dont le type est un type générique (c'est-à-dire un type quelconque), ou qui peuvent être paramétrés par une constante de type intégral. Les classes template sont des classes qui contiennent des membres dont le type est générique ou qui dépendent d'un paramètre intégral.
En général, la génération du code a lieu lors d'une opération au cours de laquelle les types génériques sont remplacés par des vrais types et les paramètres de type intégral prennent leur valeur. Cette opération s'appelle l'instanciation des template. Elle a lieu lorsqu'on utilise la fonction ou la classe template pour la première fois. Les types réels à utiliser à la place des types génériques sont déterminés lors de cette première utilisation par le compilateur, soit implicitement à partir du contexte d'utilisation du template, soit par les paramètres donnés explicitement par le programmeur.

Programmation C-C++/Les templates/Déclaration des paramètres template

Les paramètres template sont, comme on l'a vu, soit des types génériques, soit des constantes dont le type peut être assimilé à un type intégral.
Déclaration des types template.
Les template qui sont des types génériques sont déclarés par la syntaxe suivante :
template <class|typename nom[=type]
 [, class|typename nom[=type]
où nom est le nom que l'on donne au type générique dans cette déclaration. Le mot clé class a ici exactement la signification de « type ». Il peut d'ailleurs être remplacé indifféremment dans cette syntaxe par le mot clé typename. La même déclaration peut être utilisée pour déclarer un nombre arbitraire de types génériques, en les séparant par des virgules. Les paramètres template qui sont des types peuvent prendre des valeurs par défaut, en faisant suivre le nom du paramètre d'un signe égal et de la valeur. Ici, la valeur par défaut doit évidemment être un type déjà déclaré.
Exemple 12-1. Déclaration de paramètres template.
template <class T, typename U, class V=int>
Dans cet exemple, T, U et V sont des types génériques. Ils peuvent remplacer n'importe quel type du langage déjà déclaré au moment où la déclaration template est faite. De plus, le type générique V a pour valeur par défaut le type entier int. On voit bien dans cet exemple que les mots clés typename et class peuvent être utilisés indifféremment.
Lorsqu'on donne des valeurs par défaut à un type générique, on doit donner des valeurs par défaut à tous les types génériques qui le suivent dans la déclaration template. La ligne suivante provoquera donc une erreur de compilation :
template <class T=int, class V>
Il est possible d'utiliser une classe template en tant que type générique. Dans ce cas, la classe doit être déclarée comme étant template à l'intérieur même de la déclaration template. La syntaxe est donc la suivante :
template <template <class Type> class Classe [...]>
où Type est le type générique utilisé dans la déclaration de la classe template Classe. On appelle les paramètres template qui sont des classes template des paramètres template template. Rien n'interdit de donner une valeur par défaut à un paramètre template template : le type utilisé doit alors être une classe template déclarée avant la déclaration template.
Exemple 12-2. Déclaration de paramètre template template.
template <class T>
class Tableau
 // Définition de la classe template Tableau.
template <class U, class V, template <class T> class C=Tableau>
class Dictionnaire
 C<U> Clef;
 C<V> Valeur;
 // Reste de la définition de la classe Dictionnaire.
Dans cet exemple, la classe template Dictionnaire permet de relier des clés à leurs éléments. Ces clés et ces valeurs peuvent prendre n'importe quel type. Les clés et les valeurs sont stockées parallèlement dans les membres Clef et Valeur. Ces membres sont en fait des conteneurs template, dont la classe est générique et désignée par le paramètre template template C. Le paramètre template de C est utilisé pour donner le type des données stockées, à savoir les types génériques U et V dans le cas de la classe Dictionnaire. Enfin, la classe Dictionnaire peut utiliser un conteneur par défaut, qui est la classe template Tableau.
Pour plus de détails sur la déclaration des classes template, voir la Section 12.3.2.
12.2.2. Déclaration des constantes template
La déclaration des paramètres template de type constante se fait de la manière suivante :
template <type paramètre[=valeur][, ...]>
où type est le type du paramètre constant, paramètre est le nom du paramètre et valeur est sa valeur par défaut. Il est possible de donner des paramètres template qui sont des types génériques et des paramètres template qui sont des constantes dans la même déclaration.
Le type des constantes template doit obligatoirement être l'un des types suivants :
Ce sont donc tous les types qui peuvent être assimilés à des valeurs entières (entiers, énumérés ou adresses).
Exemple 12-3. Déclaration de paramètres template de type constante.
template <class T, int i, void (*f)(int)>
Cette déclaration template comprend un type générique T, une constante template i de type int, et une constante template f de type pointeur sur fonction prenant un entier en paramètre et ne renvoyant rien.

Programmation C-C++/Les templates/Fonctions et classes template