Question Utilisez 'class' ou 'typename' pour les paramètres du template? [dupliquer]


Dupliquer possible:
Différence C ++ des mots-clés 'typename' et 'class' dans les modèles 

Lorsque vous définissez un modèle de fonction ou un modèle de classe en C ++, vous pouvez écrire ceci:

template <class T> ...

ou on peut écrire ceci:

template <typename T> ...

Y a-t-il une bonne raison de préférer l'un à l'autre?


J'ai accepté la réponse la plus populaire (et intéressante), mais la vraie réponse semble être "Non, il n'y a pas de bonne raison de préférer l'un à l'autre".

  • Ils sont équivalents (sauf comme indiqué ci-dessous).
  • Certaines personnes ont des raisons de toujours utiliser typename.
  • Certaines personnes ont des raisons de toujours utiliser class.
  • Certaines personnes ont des raisons d'utiliser les deux.
  • Certaines personnes ne se soucient pas de celui qu'ils utilisent.

Notez cependant, dans le cas de modèle de modèle paramètres, utilisation de class au lieu de typename est requis. Voir La réponse de user1428839 au dessous de. (Mais ce cas particulier n'est pas une question de préférence, c'est une exigence de la langue.) (Aussi cela va changer avec c++17)


522
2017-10-17 17:47


origine


Réponses:


Stan Lippman a parlé de cela ici. Je pensais que c'était intéressant.

Résumé: Stroustrup utilisé à l'origine class spécifier des types dans les modèles pour éviter d'introduire un nouveau mot-clé. Certains membres du comité craignaient que cette surcharge du mot-clé soit source de confusion. Plus tard, le comité a introduit un nouveau mot-clé typename pour résoudre l'ambiguïté syntaxique, et a décidé de le laisser également être utilisé pour spécifier les types de modèles pour réduire la confusion, mais pour la rétrocompatibilité, class gardé sa signification surchargée.


354
2017-10-17 17:52



Selon Scott Myers, l'article 42 efficace (3e éd.) (Qui doit, bien sûr, être la réponse ultime) - la différence est "rien".

Il est conseillé d'utiliser "class" s'il est attendu que T sera toujours une classe, avec "typename" si d'autres types (int, char * quel que soit) peuvent être attendus. Considérez cela comme un indice d'utilisation.


284
2017-10-17 17:52



En plus de tous les postes ci-dessus, l’utilisation du class mot-clé est forcé (jusqu'à et y compris C ++ 14) lorsqu'il s'agit de modèle de modèle paramètres, par exemple:

template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };

Dans cet exemple, typename Container aurait généré une erreur de compilation, quelque chose comme ceci:

error: expected 'class' before 'Container'

136
2017-10-17 20:21



Je préfère utiliser le nom de fichier parce que je ne suis pas un fan de mots-clés surchargés (jeez - combien de significations différentes static avoir pour différents contextes différents?).


45
2017-10-17 19:26



est une différence, et vous devriez préférer class à typename.

Mais pourquoi?

typename est illégal pour les arguments de modèle de modèle, afin d'être cohérent, vous devez utiliser class:

template<template<class> typename MyTemplate, class Bar> class Foo { };    //  :(
template<template<class>    class MyTemplate, class Bar> class Foo { };    //  :)

12
2017-10-17 17:47



En réponse à Mike B, Je préfère utiliser 'class' car, dans un template, 'typename' a une signification surchargée, mais 'class' ne l'est pas. Prenez cet exemple de type entier vérifié:

template <class IntegerType>
class smart_integer {
public: 
    typedef integer_traits<Integer> traits;
    IntegerType operator+=(IntegerType value){
        typedef typename traits::larger_integer_t larger_t;
        larger_t interm = larger_t(myValue) + larger_t(value); 
        if(interm > traits::max() || interm < traits::min())
            throw overflow();
        myValue = IntegerType(interm);
    }
}

larger_integer_t est un nom dépendant, il nécessite donc 'typename' pour le précéder afin que l'analyseur puisse le reconnaître larger_integer_t est un type. classe, d'autre part, n'a pas une telle signification surchargée.

Cela ... ou je suis juste paresseux au fond. Je tape beaucoup plus souvent 'class' que 'typename', et trouve donc beaucoup plus facile à taper. Ou cela pourrait être un signe que j'écris trop de code OO.


9



Juste l'histoire pure. Citation de Stan Lippman:

La raison de ces deux mots clés est historique. Dans la spécification de modèle d'origine, Stroustrup réutilisait le mot-clé de classe existant pour spécifier un paramètre de type plutôt que d'introduire un nouveau mot-clé qui pouvait bien sûr interrompre les programmes existants. Ce n'est pas qu'un nouveau mot-clé n'a pas été pris en compte, mais simplement qu'il n'a pas été jugé nécessaire compte tenu de sa perturbation potentielle. Et jusqu'à la norme ISO-C ++, c'était le seul moyen de déclarer un paramètre de type.

Mais il faut utiliser nom de fichier plutôt que classe! Consultez le lien pour plus d'informations, mais pensez au code suivant:

template <class T>
class Demonstration { 
public:
void method() {
   T::A *aObj; // oops ...
};

9



Cela n'a pas d'importance du tout, mais la classe donne l'impression que T ne peut être qu'une classe, alors que cela peut bien sûr être n'importe quel type. Donc, le nom de fichier est plus précis. D'un autre côté, la plupart des gens utilisent la classe, ce qui est probablement plus facile à lire en général.


7