types de classes accès bases dépendantes
-
21-08-2019 - |
Question
Est-ce que quelqu'un sait pourquoi l'aide-déclarations ne semblent pas travailler pour l'importation des noms de type de classes de base dépendantes? Ils travaillent pour les variables membres et fonctions, mais au moins dans GCC 4.3, ils semblent être ignorés pour les types.
template <class T>
struct Base
{
typedef T value_type;
};
template <class T>
struct Derived : Base<T>
{
// Version 1: error on conforming compilers
value_type get();
// Version 2: OK, but unwieldy for repeated references
typename Base<T>::value_type get();
// Version 3: OK, but unwieldy for many types or deep inheritance
typedef typename Base<T>::value_type value_type;
value_type get();
// Version 4: why doesn't this work?
using typename Base<T>::value_type;
value_type get(); // GCC: `value_type' is not a type
};
J'ai une classe de base avec un ensemble de typedefs style allocateur que je voudrais hériter à travers plusieurs niveaux d'héritage. La meilleure solution que je l'ai trouvé à ce jour est la version 3 ci-dessus, mais je suis curieux de savoir pourquoi ne semble pas la version 4 de travailler. GCC accepte l'aide de déclaration, mais semble l'ignorer.
J'ai vérifié la norme C ++, C Prog. Lang. 3e éd. [Stroustrup], et C ++ Modèles [Vandevoorde, Josuttis], mais aucun ne semble répondre si l'utilisation de déclarations solennelles peuvent être appliquées à des types de classe de base à charge.
Dans le cas où il aide à voir un autre exemple, ici est le même question posée , mais pas vraiment répondu, sur la liste de diffusion GCC. Le demandeur indique qu'il a vu « en utilisant typename » ailleurs, mais que GCC ne semble pas soutenir. Je n'ai pas un autre compilateur conforme disponible pour le tester.
La solution
Comme Richard Corden souligne, cette question a été abordée dans le C ++ standard de base Langue Defect Rapports après la norme 2003 a été ratifiée: Comment le typename / modèle de mots-clés interagir avec l'aide-déclarations?
Proposition de résolution (Avril 2003, révisée Octobre 2003):
Ajouter un nouveau paragraphe au fond de 7.3.3 [namespace.udecl]:
Si une utilisation de déclaration utilise la typename mot-clé et spécifie un nom dépendante (14.7.2 [temp.dep]), le nom introduit par le est considérée comme utilisant déclaration un typedef-name (7.1.3 [dcl.typedef]).
Ce texte ne semble pas apparaître dans la norme Deuxième édition du 15 Octobre 2003.
GCC ne supporte pas encore cette résolution, comme expliqué dans bug 14258 :
------- Commentaire # 3 De Giovanni Bajo 2004-02-27 12:47 [réponse] ------- La problème est que notre USING_DECL ne enregistrer le « typename », c'est la fait qu'il est d'un type qui est importés à travers elle. Cette habitude de travailler grâce au nom de type implicite extension, je crois.
bug 21484 indique que 'l'utilisation typename' travaille sur Comeau et compilateurs Intel. Parce que MSVC traite tous les noms comme dépendants, la construction est inutile (mais autorisée) pour ce compilateur.
fixe dans GCC 4.7 le 13 déc 2011
Autres conseils
Vous n'avez pas inclus un spécificateur d'accès (public / protégé / privé) dans le modèle de base avant de déclarer la typedef pour base :: value_type. Par conséquent, la valeur par défaut privée et ne sont pas accessibles dans les classes dérivées de la base.