2011-08-11 5 views
19

Ce que je lis dans la norme C++ sur les noms de classe injectés contredit (comme je le vois) le comportement d'un exemple de programme que je présenterai sous peu. Voici ce que je lis:Le nom ambigu de la classe injectée n'est pas une erreur

  • De 3.4 (paragraphe 3)

    La classe nom injecté d'une classe (article 9) est également considéré comme un membre de cette classe pour la fins de dissimulation de nom et de recherche.

  • De 9 (paragraphe 2)

    Un nom de classe est inséré dans le champ d'application dans laquelle elle est déclarée immédiatement après le nom de la classe est vu. Le nom de classe est également inséré dans la portée de la classe elle-même; c'est ce qu'on appelle le nom-classe injecté. Pour les besoins de la vérification de l'accès, le nom de la classe est traité comme s'il s'agissait d'un nom de membre public.

De ceux-ci, je comprends que ce qui suit est une unité de traduction bien formé et il compile avec succès.

#include <vector> 
class X: std::vector<int> 
{ 
    vector mem; 
}; 

Cependant, je suppose que ce qui suit aurait dû produire une erreur, mais il n'a pas

#include <vector> 
class X: std::vector<int>, std::vector<char> 
{ 
    vector mem; //compiles OK... mem is apparently std::vector<int> 
}; 

Puisque le nom vector est injecté dans les deux std::vector<int> et std::vector<char> que comme membre du public name, alors il devrait être hérité par X et par conséquent le nom vector dans X devrait être ambigu. Est-ce que je manque quelque chose?

P.S. J'utilise MSVC9.0

+1

+1. bonne question – Nawaz

+0

Est-ce que la deuxième clause ne fait pas référence à «X» dans votre exemple? C'est à dire. est le * nom-classe-injecté * pas "X" plutôt que "vecteur"? Je pense que c'est le cas, et si c'est le cas, les guillemets ne sont pas pertinents pour le code, mais le comportement de ce compilateur ne semble pas correct non plus il n'y a aucune raison de préférer 'std :: vector ' sur 'std :: vector 'et cela signifie qu'une erreur d'ambiguïté doit être déclenchée. –

+1

@David: Dans la classe 'X' oui, mais' vector' est injecté comme un nom public dans les deux bases ... Il devrait donc être visible (et ambigu) dans 'X' - comme dans le premier exemple –

Répondre

15

je l'ai trouvé! C'est juste là dans la norme! J'avais raison! Il devrait être ambigu!

Article 14.6.1 Paragraphe

Une recherche qui trouve une classe nom injecté (10.2) peut entraîner une ambiguïté dans certains cas (par exemple, si elle se trouve dans plus de un classe de base). Si tous les noms de classes injectés trouvés font référence à des spécialisations du même modèle de classe, et si le nom est suivi d'une liste template-argument, la référence fait référence au modèle de classe lui-même et non à une spécialisation de celui-ci et n'est pas ambiguë.[Exemple:

template <class T> struct Base { }; 
template <class T> struct Derived: Base<int>, Base<char> 
{ 
    typename Derived::Base b; // error: ambiguous typename 
    Derived::Base<double> d; // OK 
}; 

-end exemple]

Bottom line: Ceci est encore un autre compilateur Microsoft BOGUE. La désactivation des extensions de langue n'aide pas non plus.

4

Non, rien ne vous manque, et votre compilateur semble se comporter en buggy. Vous pouvez voir comment il gère gcc ici: http://ideone.com/MI9gz

Son message d'erreur est:

prog.cpp:4:4: error: reference to 'vector' is ambiguous 
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_vector.h:171:5: error: candidates are: class std::vector<char> std::vector<char>::vector 
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_vector.h:171:5: error:     class std::vector<int> std::vector<int>::vector 
+0

Ah, oui, en effet! Je viens de trouver la citation de la norme moi-même (voir ma réponse) –

Questions connexes