Différence entre les mots-clés 'Nom typé' et 'classe' dans les modèles?

pour les modèles j'ai vu les deux déclarations:

template < typename T >
template < class T >

quelle différence?

et que signifient exactement ces mots-clés dans l'exemple suivant (tiré de L'article de Wikipedia allemand sur les modèles)?

template < template < typename, typename > class Container, typename Type >
class Example
{
     Container< Type, std::allocator < Type > > baz;
};
347
demandé sur Rakete1111 2010-01-08 00:59:41

5 réponses

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 y a des cas spécifiques où il y a une différence entre typename et class .

le premier est dans le cas des types dépendants. typename est utilisé pour déclarer lorsque vous faites référence à une type imbriqué qui dépend d'un autre paramètre de template, tel que le typedef dans cet exemple:

template<typename param_t>
class Foo
{
    typedef typename param_t::baz sub_t;
};

le deuxième que vous montrez réellement dans votre question, bien que vous pourriez ne pas le réaliser:

template < template < typename, typename > class Container, typename Type >

en spécifiant un modèle de gabarit , le mot-clé class doit être utilisé comme ci-dessus -- il est pas interchangeable avec typename dans ce cas (note: 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 manqués, mais la ligne de fond est: ces deux mots-clés ne sont pas équivalents, et ce sont des cas communs où vous devez utiliser l'un ou l'autre.

301
répondu Aaron Klotz 2017-06-26 13:28:24

pour nommer les paramètres du modèle, typename et class sont équivalents. §14.1.2:

Il n'y a pas de différence sémantique entre la classe et le nom dans un template-parameter.

typename est cependant possible dans un autre contexte en utilisant templates - pour indiquer au compilateur que vous faites référence à un type dépendant. §14.6.2:

Un nom utilisé dans un modèle déclaration ou définition et qui dépend de un modèle à paramètre est supposé ne pas nommer un type à moins que le nom applicable recherche trouve un nom de type ou le nom est qualifié par le mot-clé typename.

exemple:

typename some_template<T>::some_type

sans typename le compilateur ne peut pas dire en général si vous faites référence à un type ou non.

71
répondu Georg Fritzsche 2017-01-29 01:33:28

bien qu'il n'y ait pas de différence technique, j'ai vu les deux utilisés pour désigner des choses légèrement différentes.

pour un modèle qui devrait 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 c'est purement une chose de style que certaines personnes utilisent. Non prescrit par la norme ou appliqué par les compilateurs

17
répondu Michael Anderson 2010-01-07 22:12:23
  1. pas de différence
  2. paramètre de type de modèle Container est lui-même un modèle avec deux paramètres de type.
6
répondu Nikolai Fetissov 2010-01-07 22:03:07

ce morceau de snippet est de C++ primer book. Même si je suis sûr que c'est mal.

chaque paramètre de type doit être précédé du mot-clé class ou du nom de type:

// 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 de façon interchangeable à l'intérieur d'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 classe pour désigner un modèle type de paramètre. Après tout, nous pouvons utiliser les types intégrés (nonclass) comme argument de type de modèle. De plus, typename indique plus clairement que le nom qui suit est un nom de type. Cependant, le nom de type a été ajouté à C++ Après que les gabarits aient été déjà largement utilisés; certains programmeurs continuent à utiliser la classe exclusivement

3
répondu K.K 2012-12-08 05:17:21