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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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
[modifier | modifier le wikicode]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 :
- type intégral (char, wchar_t, int, long, short et leurs versions signées et non signées) ou énuméré ;
- pointeur ou référence d'objet ;
- pointeur ou référence de fonction ;
- pointeur sur membre.
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
[modifier | modifier le wikicode]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.