Eu tenho o seguinte código:
namespace A {
struct Foo {
int a;
};
}
struct Foo {
int b;
};
struct Bar : public A::Foo {
Bar(Foo foo) {
c = foo.b;
}
int c;
};
Compiladores C ++ reclamam em "c = foo.b" porque A :: Foo não possui um membro chamado b. Se eu alterar o tipo de parâmetro Bar com :: Foo, ele funcionará.
Minha pergunta é qual é o racional por trás desse comportamento (suponho que tenha a ver com o fato de a herança fazer Bar entrar no espaço de nomes A, mas não consigo encontrar nenhuma documentação para apoiar essa teoria.
c++
inheritance
namespaces
language-lawyer
Vincent Le Ligeour
fonte
fonte
A
, que você pode ver se deixarBar
herdar de outra estruturaA
. Então não há ambiguidade. É mais como se a herança adicionasse tudo, desdeA::Foo
atéBar
a resolução deFoo
atéA::Foo
. Desculpe, não posso realmente expressar isso de forma mais precisa.Respostas:
Toda classe tem seu nome inserido como membro. Então você pode nomear
A::Foo::Foo
. Isso é chamado de nome da classe injetada.Como a pesquisa de nome não qualificado do tipo de argumento começa no escopo da classe
Bar
, ela continuará no escopo de sua classe base para contabilizar qualquer membro lá. E será encontradoA::Foo::Foo
como um nome de tipo.Se você deseja usar o nome do tipo global, qualifique-o simplesmente pelo espaço para nome (global) ao redor.
Que está fazendo uma pesquisa totalmente qualificada em um escopo em que o nome da classe injetada não aparece.
Para uma pergunta "por que", consulte
fonte
struct Bar:: A::Foo::Foo::Foo::Foo::Foo {};
mas há contextos em queA::Foo::Foo
designa o construtor e, portanto, não é possível continuar adicionando quantosFoo
você desejar. Isto é semelhante (mas com um mecanismo completamente diferente) para o fato de que você pode chamar uma funçãof
desta forma:(************f)()
.Não é uma resposta completa, apenas o código que mostra (uma vez que é compilado) que
Bar
não entra nonamespace A
. Você pode ver que quando herdandoA::Foo1
não há nenhum problema com a ambiguidade deFoo
que seria diferente se essa herança permiteBar
entrarA
.fonte