Pour les modèles, j'ai vu les deux déclarations:
template < typename T >
template < class T >
Quelle est la différence?
Et que signifient ces mots clés dans l'exemple suivant (extrait de l'article de Wikipédia en allemand sur les modèles)?
template < template < typename, typename > class Container, typename Type >
class Example
{
Container< Type, std::allocator < Type > > baz;
};
typename
et class
sont interchangeables dans le cas de base de la spécification d'un modèle:
template<class T>
class Foo
{
};
et
template<typename T>
class Foo
{
};
sont équivalents.
Cela dit, il existe des cas spécifiques où il existe une différence entre typename
et class
.
Le premier concerne les types dépendants. typename
est utilisé pour déclarer lorsque vous référencez un type imbriqué qui dépend d'un autre paramètre de modèle, tel que le typedef
dans cet exemple:
template<typename param_t>
class Foo
{
typedef typename param_t::baz sub_t;
};
La deuxième que vous montrez réellement dans votre question, même si vous ne le réalisez peut-être pas:
template < template < typename, typename > class Container, typename Type >
Lorsque vous spécifiez un modèle de modèle, le mot clé class
DOIT être utilisé comme ci-dessus - il est pas interchangeable avec typename
dans ce cas (remarque: depuis C++ 17, les deux mots-clés sont autorisés dans ce cas) .
Vous devez également utiliser class
lors de l'instanciation explicite d'un modèle:
template class Foo<int>;
Je suis sûr qu'il y a d'autres cas que j'ai oubliés, mais l'essentiel est: ces deux mots clés ne sont pas équivalents et il existe des cas courants dans lesquels vous devez utiliser l'un ou l'autre.
Pour nommer les paramètres de modèle, typename
et class
sont équivalents. §14.1.2:
Il n'y a pas de différence sémantique entre class et nomtype dans un paramètre de modèle.
typename
est toutefois possible dans un autre contexte lorsque vous utilisez des modèles - pour indiquer au compilateur que vous faites référence à un type dépendant. § 14.6.2:
Un nom utilisé dans une déclaration ou une définition de modèle et dépendant d'un paramètre de modèle est supposé ne pas nommer un type, sauf si la recherche de nom applicable trouve un nom de type ou si le nom est qualifié par le mot clé nom_type.
Exemple:
typename some_template<T>::some_type
Sans typename
le compilateur ne peut pas dire en général si vous vous référez à un type ou non.
Bien qu’il n’y ait pas de différence technique, j’ai vu les deux qualifier de choses légèrement différentes.
Pour un modèle qui doit accepter n'importe quel type en tant que T, y compris les éléments intégrés (tels qu'un tableau)
template<typename T>
class Foo { ... }
Pour un modèle qui ne fonctionnera que lorsque T est une vraie classe.
template<class T>
class Foo { ... }
Mais gardez à l'esprit que ceci est purement une chose de style que certaines personnes utilisent. Non mandaté par la norme ou imposé par les compilateurs
Container
est lui-même un modèle avec deux paramètres de type.Ce fragment de code provient du livre d’apprêt c ++. Bien que je sois sûr que ce soit faux.
Chaque paramètre de type doit être précédé du mot clé class ou typename:
// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);
Ces mots clés ont la même signification et peuvent être utilisés indifféremment dans une liste de paramètres de modèle. Une liste de paramètres de modèle peut utiliser les deux mots-clés:
// ok: no distinction between typename and class in a template parameter list
template <typename T, class U> calc (const T&, const U&);
Il peut sembler plus intuitif d’utiliser le mot-clé typename plutôt que class pour désigner un paramètre de type template. Après tout, nous pouvons utiliser les types intégrés (hors classe) comme argument de type modèle. De plus, typename indique plus clairement que le nom qui suit est un nom de type. Cependant, nom_type a été ajouté à C++ après que les modèles étaient déjà largement utilisés; certains programmeurs continuent à utiliser exclusivement la classe