8
votes

GCC et mot-clé de classe

Je sais que typename code> et classes code> Les mots-clés sont interchangeables dans des arguments de modèle, mais je pensais que typename code> est autorisé pour les spécifications de classes imbriquées. Une fois que j'ai accidentellement écrit mal " classe code>" au lieu de " typename code>" pour une classe imbriquée. Et j'ai trouvé, c'est que GCC accepte la classe code> là aussi, afin que vous puissiez écrire quelque chose comme: p> xxx pré>

dans votre modèle. P>

Est-ce un bogue GCC ou la norme autorise-t-elle vraiment cette syntaxe? P>

mise à jour: Exemple de code: P>

template <typename T>
void test()
{
     class std::vector<T>::iterator it;
}


7 commentaires

Pourquoi ne postez-vous pas le code? et quelle version de GCC?


Cela fonctionne pour toute utilisation de la classe au lieu de typename. J'ai essayé ceci sur GCC 4.1.2 et 4.3.4


Dupliqué possible de Quelle est la différence entre "Modèle " et "Modèle "?


@RUBENVB: NAH, il s'agit de la typename avant le type imbriqué (DEF) s.


@Xeo: Y a-t-il une différence fondamentale? J'ai aussi trouvé le typename <-> la classe de classe Pêchy et n'a jamais eu une réponse complète et complète.


@RUBENVB: Oui, il y a une différence. Dans les déclarations de modèles, ils sont effectivement interchangeables. Pas pour les types imbriqués cependant.


Cette question peut être plus claire si vous avez utilisé la terminologie correcte: «Nom de la dépendance» (plutôt que «classe imbriquée»).


6 Réponses :


-1
votes

Je suis toujours une perte à ce qui se passe. Je mettrais un commentaire si mettre le code il n'y avait pas problématique.

class Foo::Bar;


0 commentaires

0
votes

Ideone montre un joli message d'erreur lorsque le nom de la personne dépendante ne résolve pas à une classe. Votre exemple ne fonctionne que car itérateur est en effet une classe . :)


edit : MSVC ne parvient pas à compiler même si la personne à charge est en effet une classe,

Erreur C2242 : Typedef nom ne peut pas suivre la classe / structure / Union

edit 2 : Cela semble être un bogue MSVC, comme g ++ et Comeau Compiler en ligne, bien si le nom de la personne à charge est une classe.


0 commentaires

1
votes

Il ne compile pas avec Comeau Online (Comeau C / C ++ 4.3.10.1 (US 6 2008 11:28:09)), Ainsi, au moins l'un des deux compilateurs a un bogue.

error: typedef "iterator" may not be used in an elaborated
          type specifier
       class std::vector<T>::iterator it;


1 commentaires

Intéressant, je voudrais maintenant savoir ce que la norme dit à ce sujet.



1
votes

Certes, la norme semble confirmer que le typename doit être utilisé. Du 14.6 / 2:

Nom utilisé dans une déclaration ou une définition de modèle et dépend d'un paramètre de modèle est supposé ne pas nommer un type à moins que la recherche de nom applicable ne trouve qu'un nom de type ou le nom est qualifié par le mot-clé Typename.


0 commentaires

2
votes

Section 14.6 ("Résolution du nom") dans l'ISO 14886: 2003 semble être la définition de la manière dont cela est censé fonctionner. Le paragraphe 3 dit:

A ID qualifié qui fait référence à un type et dans lequel le spécificateur de nom niché dépend du paramètre modèle (14.6 .2) doit être préfixé par le mot-clé typename pour indiquer que l'identifiant qualifié désigne un type, formant un spécificateur de type élaboré ( 7.1.5.3).

Aucune mention du mot clé classe . Je pense que c'est un bug de GCC.


1 commentaires

Merci, cela devrait donc être un bug comme je soupçonné. Je vais vérifier avec la dernière version du GCC et signalera ce bogue s'il est toujours là.



2
votes

Classe A :: B est un spécificateur de type élaboré. Nom Recherche pour un spécificateur de type élaboré Ignore les noms de type. Donc, si vous analysez un modèle, vous pouvez assumer deux choses:

  • Lorsque nous sommes instantanés et que nous faisons la nomenclature pour B , la recherche d'un nom nous donne un type ou des erreurs informatiques (ne trouverait aucun nom).

    en C ++ 0x pour cette raison, Classe A :: B n'a pas besoin typename (vous ne pouvez pas la mettre n'importe où de toute façon sur un spécificateur de type élaboré). C ++ 03 ne permet pas que GCC semble mettre en œuvre les règles C ++ 0X sous forme d'extension.

    Ce n'est pas particulièrement mauvais. Chaque compilateur réel implémente des règles sensibles et faciles à mettre en œuvre dans leur version C ++ 03, en leur nom, même si formellement, ils auraient besoin de le rejeter. Cependant, classe A :: B doit recherche d'un nom de classe. S'il s'agit simplement d'une TLECDEF, la recherche du spécificateur de type élaboré n'est pas valide.

    Notez que Classe A :: B est le seul moyen d'ignorer les noms de type de type dans une recherche (sauf pour les cas d'arcanes comme avant un :: dans un nom qualifié qui ont des règles spéciales similaires). Par exemple, xxx

    Si vous compilez sur C ++ 0x, et que vous utilisez Classe T :: Type T; , le code devient alors valide, Parce que Classe T :: Type ignore le membre de données, mais trouve la classe imbriquée.


1 commentaires

C'est donc une extension C ++ 0x? Ok, bon de savoir ça. Cependant, il est un peu étrange qu'il soit activé par défaut.