J'ai le code suivant:
namespace A {
struct Foo {
int a;
};
}
struct Foo {
int b;
};
struct Bar : public A::Foo {
Bar(Foo foo) {
c = foo.b;
}
int c;
};
Les compilateurs C ++ se plaignent à "c = foo.b" car A :: Foo n'a pas de membre nommé b. Si je change le type de paramètre Bar avec :: Foo ça marche.
Ma question est de savoir quel est le rationnel derrière ce comportement (je suppose que cela a à voir avec le fait que l'héritage oblige Bar à entrer dans l'espace de noms A, mais je ne trouve aucune documentation à l'appui de cette théorie.
c++
inheritance
namespaces
language-lawyer
Vincent Le Ligeour
la source
la source
A
, que vous pouvez voir si vous laissezBar
hériter d'une autre structureA
. Il n'y a alors aucune ambiguïté. Cela ressemble plus à l'héritage qui ajoute tout deA::Foo
à,Bar
y compris la résolution deFoo
àA::Foo
. Désolé, je ne peux pas vraiment l'exprimer plus précisément.Réponses:
Chaque classe a son nom inséré en tant que membre. Vous pouvez donc nommer
A::Foo::Foo
. Cela s'appelle le nom de classe injecté.Étant donné que la recherche de nom non qualifié du type d'argument commence dans la portée de la classe
Bar
, elle continuera dans la portée de sa classe de base pour y prendre en compte tout membre. Et il trouveraA::Foo::Foo
un nom de type.Si vous souhaitez utiliser le nom de type global, qualifiez-le simplement par son espace de noms (global) environnant.
Ce qui fait une recherche complète dans une portée où le nom de classe injecté n'apparaît pas.
Pour une question de "pourquoi" de suivi, voir
la source
struct Bar:: A::Foo::Foo::Foo::Foo::Foo {};
mais il y a des contextes oùA::Foo::Foo
désigne le constructeur et donc là, vous ne pouvez pas continuer à en ajouter autantFoo
que vous le souhaitez. Ceci est similaire (mais avec un mécanisme complètement différent) du fait que vous pouvez appeler une fonction def
cette façon:(************f)()
.Pas une réponse complète, seulement du code qui montre (puisqu'il compile) qui
Bar
n'entre pas dans lenamespace A
. Vous pouvez voir que lors de l'héritageA::Foo1
il n'y a pas de problème d'ambiguïtéFoo
qui serait différent si cet héritage laisseBar
entrerA
.la source