183 votes

Officiellement, à quoi sert typename?

J'ai parfois vu des messages d'erreur vraiment indéchiffrables cracher par gcc lors de l'utilisation de templates ... Plus précisément, des problèmes se produisaient lorsque des déclarations apparemment correctes provoquaient des erreurs de compilation très étranges qui disparaissaient comme par magie en préfixant le mot clé "typename" à le début de la déclaration ... (Par exemple, la semaine dernière, je déclarais deux itérateurs en tant que membres d'une autre classe basée sur des modèles et je devais le faire) ...

Quelle est l'histoire sur typename?

283voto

Naveen Points 37095

Voici la citation de Josuttis livre:

Le mot-clé typename a été introduit à spécifier l'identificateur de suit est un type. Envisager l' exemple suivant:

template <class T>
Class MyClass
{
  typename T::SubType * ptr;
  ...
};

Ici, le nom est utilisé pour préciser que Sous-type est un type de classe de T. Ainsi, le ptr est un pointeur vers le type T::Sous-Type. Sans typename, sous-type serait considéré comme un membre statique. Ainsi

T::SubType * ptr

serait une multiplication de la valeur Sous-type du type T avec le ptr.

44voto

Xinus Points 7693

Stan Lippman du BLog suggère :-

Stroustrup réutilisé la classe existante mot-clé pour spécifier un paramètre de type plutôt que d'introduire un nouveau mot-clé qui pourraient briser existant de programmes. Ce n'est pas qu'un nouveau mot-clé n'avait pas été considérée, mais seulement qu'il n'a pas été jugé nécessaire, compte tenu de son les risques de perturbation. Et jusqu'à la ISO-standard C++, c'était la seule façon de déclarer un paramètre de type.

Donc, fondamentalement, Stroustrup réutilisés mot-clé class, sans introduire un nouveau mot-clé qui est changé afterworlds dans la norme pour les raisons suivantes

Comme l'exemple donné

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

langue grammaire méconnaît il^ T::A *aObj; comme une expression arithmétique si nouveau mot-clé est introduite appelée typename

typename T::A* a6;

il demande au compilateur de traiter le rapport suivant comme une déclaration.

Puisque le mot-clé était sur la liste de paie, diable, pourquoi ne pas corriger la confusion causée de l'original de la décision de réutiliser l' mot-clé class.

C'est pourquoi nous avons à la fois

Vous pouvez jeter un oeil sur le post, il va certainement vous aider, j'ai juste extrait le plus peut

18voto

moonshadow Points 28302

Considérons le code

 template<class T> somefunction( T * arg )
{
    T::sometype x; // broken
    .
    .
 

Malheureusement, le compilateur n'est pas obligé d'être psychique, et ne sait pas si T :: quelque chose finira par faire référence à un nom de type ou à un membre statique de T. Donc, on utilise typename pour le dire :

 template<class T> somefunction( T * arg )
{
    typename T::sometype x; // works!
    .
    .
 

10voto

AndreyT Points 139512

Dans certaines situations où vous référer à un membre de la dite dépendante du type (qui signifie "dépend de paramètre de modèle"), le compilateur ne peut pas toujours sans ambiguïté en déduire le sens sémantique de la résultante de construire, car il ne sait pas quel genre de nom (c'est à dire si c'est un nom, un type, un nom d'un membre de données ou le nom de quelque chose d'autre). Dans des cas comme celui que vous avez à lever l'ambiguïté de la situation, indiquez explicitement au compilateur que le nom appartient à un nom défini comme un membre de ce type de charge.

Par exemple

template <class T> struct S {
  typename T::type i;
};

Dans cet exemple, le mot-clé typename nécessaires pour le code à compiler.

La même chose se produit lorsque vous voulez faire référence à un modèle de membre de type dépendant, c'est à dire un nom qui désigne un modèle. Vous avez également à aider le compilateur en utilisant le mot - template, même s'il est placé différemment

template <class T> struct S {
  T::template ptr<int> p;
};

Dans certains cas, il peut être nécessaire d'utiliser les deux

template <class T> struct S {
  typename T::template ptr<int>::type i;
};

(si j'ai la syntaxe correcte).

Bien sûr, un autre rôle: le mot-clé typename sera utilisé dans le modèle de déclarations de paramètres.

6voto

Phillip Ngan Points 4303

Deux utilisations:

  1. Comme mot-clé d'argument de modèle (au lieu de 'classe')
  2. Un mot clé typename indique au compilateur qu'un identifiant est un type (plutôt qu'une variable membre statique)
 template <typename T> class X  // [1]
{
    typename T::Y _member;  // [2] 
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X