web-dev-qa-db-fra.com

Utilisez 'class' ou 'typename' pour les paramètres de template?

Duplicate 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'une à l'autre?


J'ai accepté la réponse la plus populaire (et la plus intéressante), mais la vraie réponse semble être "Non, il n'y a pas de bonne raison de préférer l'une à 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 celle qu'elles utilisent.

Notez cependant qu'avant C++ 17, dans le cas de paramètres de modèle , l'utilisation de class au lieu de typename était requise. Voir réponse de l'utilisateur1428839 ci-dessous. (Mais ce cas particulier n'est pas une question de préférence, c'était une exigence de la langue.)

567
Kristopher Johnson

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

Résumé : À l'origine, Stroustrup utilisait class pour spécifier les types dans les modèles afin d'éviter d'introduire un nouveau mot-clé. Certains membres du comité craignent que cette surcharge du mot-clé ne crée de la confusion. Plus tard, le comité a présenté un nouveau mot clé typename pour résoudre les ambiguïtés syntaxiques et a décidé de le laisser également être utilisé pour spécifier les types de modèles afin de réduire les risques de confusion. Toutefois, pour des raisons de compatibilité ascendante, class a gardé son sens surchargé.

387
itsmatt

Selon Scott Myers, Effective C++ (3e éd.), Élément 42 (qui doit bien entendu être la réponse ultime), la différence est "rien".

Le conseil est d'utiliser "classe" s'il est prévu que T sera toujours une classe, avec "nom_type" si d'autres types (int, char * peu importe) peuvent être attendus. Considérez cela comme un indice d'utilisation.

301
DarenW

En complément de tous les articles ci-dessus, l'utilisation du mot clé class est forcé (jusqu’à C++ 14 inclus) lorsqu’il s’agit de template template 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, qui ressemble à ceci:

error: expected 'class' before 'Container'
145
JorenHeit

Je préfère utiliser nom_type car je ne suis pas fan des mots-clés surchargés (combien de significations différentes static a-t-il dans différents contextes?).

47
Michael Burr

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

Mais pourquoi?

typename n'est pas autorisé pour les arguments de modèle. Par conséquent, pour ê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 { };    //  :)
15
Mehrdad

En réponse à Mike B , je préfère utiliser 'classe' car, dans un modèle, 'nomtype' a une signification surchargée, mais 'classe' n'en a pas. Prenons 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. Par conséquent, il est précédé par 'typename' pour que l'analyseur puisse reconnaître que larger_integer_t est un type. class , d'autre part, n'a pas cette signification surchargée.

C'est ... ou je suis juste paresseux d'esprit. Je tape beaucoup plus souvent 'class' que 'typename' et le trouve beaucoup plus facile à taper. Ou cela pourrait être un signe que j'écris trop de code OO.

9
Aaron

Juste de l'histoire pure. Citation de Stan Lippman :

La raison des deux mots-clés est historique. Dans la spécification du modèle d'origine, Stroustrup a réutilisé le mot-clé de classe existant pour spécifier un paramètre de type plutôt que d'introduire un nouveau mot-clé susceptible de détruire 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 en raison 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 typename plutôt que class ! Voir le lien pour plus d'informations, mais pensez au code suivant:

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

Cela n’a aucune importance, mais la classe donne l’impression que T ne peut être qu’une classe, alors qu’il peut bien sûr être de tout type. Donc, typename est plus précis. D'autre part, la plupart des gens utilisent la classe, ce qui est probablement plus facile à lire en général.

7

Autant que je sache, peu importe celui que vous utilisez. Ils sont équivalents aux yeux du compilateur. Utilisez celui que vous préférez. J'utilise normalement la classe.

1
Grant Limberg