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;
};
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.
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.
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
- pas de différence
- paramètre de type de modèle
Container
est lui-même un modèle avec deux paramètres de type.
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