Spécifications de modèle
La déclaration d'template spécifie un ensemble de classes paramétrées ou de fonctions.
template < template-parameter-list > declaration
Notes
La liste de paramètres de modèle est une liste des paramètres de modèle (avec la virgule comme séparateur) qui peuvent être des paramètres avec types (dans le formulaire identifiant de classe, identifiant de nom de type, outemplate < > classe la liste de modèles de paramètres listidentifier) ou sans type à utiliser dans le corps de modèle. La syntaxe d'un paramètre de modèle est l'une des opérations suivantes :
parameter-declaration
class identifier [ = typename ]
typename identifier [ = typename ]
template < template-parameter-list > class [identifier][= name]
Il est possible d'instancier un modèle de classe tout comme on instancierait une classe normale, mais vous devez inclure les arguments des modèles entre des crochets pointus (<>). Ces arguments de modèles peuvent être de tout type si la liste d'arguments de modèles contient la classe ou le mot clé nom de type, ou une valeur du type approprié si l'argument est un argument sans type. Aucune syntaxe spéciale n'est requise pour appeler un modèle de fonction, même si les crochets angulaires et les arguments de modèles puissent être requis si les paramètres de modèles ne peuvent être déduits des arguments de la fonction.
La liste de paramètres de modèle est une liste de paramètres utilisés par la fonction de modèle qui spécifie quelles parties du code suivant varient. Par exemple :
template< class T, int i > class MyStack...
Dans ce cas, le modèle peut recevoir un type (class T) et un paramètre constant (int i). Le modèle utilise le type T et la constante entière i lors de l'instanciation. Dans le corps de la déclaration d'MyStack, vous devez faire référence à l'identificateur d'T.
Une déclaration de modèle lui-même ne génère pas de code ; elle spécifie une famille de classes ou de fonctions, parmi lesquels un ou plusieurs seront généré lorsque référencé par un autre code.
Les déclarations de modèles ont une portée globale, d'espace de noms ou de classe. Elles ne peuvent pas être déclarées à l'intérieur d'une fonction.
L'exemple suivant illustre la déclaration, la définition, et l'instanciation d'un modèle de classe avec un paramètre de type T et un paramètre ide modèle sans type.
// 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()
{
}
Arguments template sans type
Les paramètres du modèle sans type doivent être de types intégraux, énumération, pointeur, référence, ou pointeur vers un membre, et doivent être constant au moment de la compilation. Ils peuvent être qualifiés en tant que types constants ou volatiles. Les valeurs à virgule flottante ne sont pas autorisées comme paramètres de modèle. Les objets de type classe, structure ou union ne sont pas autorisés comme paramètres de modèle sans type, bien qu'il autorise des pointeurs sur de tes objets. Les tableaux passés comme paramètres de modèle sans type sont convertis en pointeurs. Les fonctions passées en tant que paramètres sans type sont traitées comme des pointeurs fonctions. Il n'est pas possible d'utiliser des chaînes de littéraux comme paramètres de modèle.
Utilisation de typename dans une déclaration de modèle
Le mot clé typename peut être utilisé dans la liste de paramètres de modèle. Les déclarations suivantes de modèle sont les mêmes :
template< class T1, class T2 > class X...
template< typename T1, typename T2 > class X...
Arguments par défaut des paramètres de modèle
Les modèles de classe peuvent avoir des arguments par défaut spécifiés en utilisant le signe = suivi du type du défaut ou de sa valeur. Les modèles de fonction ne peuvent pas avoir d'arguments par défaut. Pour plus d'informations, consultez Arguments par défaut pour les modèles de classe.:
template<typename Type> class allocator {};
template<typename Type,
typename Allocator = allocator<Type> > class stack
{
};
stack<int> MyStack;
Réutilisation de paramètres de modèle
Les paramètres de modèle peuvent être réutilisés dans la liste de paramètres de modèle. Par exemple, le code suivant est autorisé:
// 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()
{
}
Modèles comme paramètres de modèle
Les paramètres de modèle peuvent eux-mêmes être des modèles. Cette construction signifie que l'argument doit être lui-même un modèle, et non une classe construite du modèle. Dans l'exemple suivant, le nom A du paramètre de modèle peut être omis pour un paramètre de modèle, car il n'existe aucune façon dont il puisse être utilisé.
// 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);
}
Sortie
5
Références comme paramètres de modèle
Visual Studio .NET. 2003 a introduit la possibilité d'utiliser des références comme paramètres de modèle sans type. Cela n'était pas autorisés dans les versions antérieures.
// 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;
}
Sortie
ri is 1
ri is 0
Instances de modèles imbriqués
Les versions de Visual Studio antérieures à Visual Studio 2005 requièrent qu'un espace blanc soient inséré entre les listes de paramètres de modèle lorsque des instances imbriquées de modèle étaient déclarées. Il permet maintenant la syntaxe suivante :
// template_specifications4.cpp
template <typename T>
class A
{
};
template <int n>
class B
{
};
int main()
{
A<B<22>>();
}