web-dev-qa-db-fra.com

Différence entre les mots-clés 'typename' et 'class' dans les modèles?

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;
};
429
Mat

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.

379
Aaron Klotz

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.

80
Georg Fritzsche

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

18
Michael Anderson
  1. Aucune différence
  2. Le paramètre de type de modèle Container est lui-même un modèle avec deux paramètres de type.
6
Nikolai Fetissov

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

4
K.K