Ich habe folgenden Code:
namespace A {
struct Foo {
int a;
};
}
struct Foo {
int b;
};
struct Bar : public A::Foo {
Bar(Foo foo) {
c = foo.b;
}
int c;
};
C ++ - Compiler beschweren sich bei "c = foo.b", weil A :: Foo kein Mitglied namens b hat. Wenn ich den Typ des Bar-Parameters mit :: Foo ändere, funktioniert es.
Meine Frage ist, was der Grund für dieses Verhalten ist (ich nehme an, es hat damit zu tun, dass die Vererbung Bar dazu bringt, in den A-Namespace einzutreten, aber ich kann keine Dokumentation finden, die diese Theorie unterstützt.
c++
inheritance
namespaces
language-lawyer
Vincent Le Ligeour
quelle
quelle
A
, den Sie sehen können, wenn SieBar
von einer anderen Struktur in erben lassenA
. Dann gibt es keine Mehrdeutigkeit. Es ist eher so, als würde die Vererbung alles vonA::Foo
bisBar
einschließlich der Auflösung vonFoo
bis hinzufügenA::Foo
. Entschuldigung, ich kann es nicht genauer ausdrücken.Antworten:
Jede Klasse hat ihren Namen als Mitglied. So können Sie benennen
A::Foo::Foo
. Dies wird als Name der injizierten Klasse bezeichnet.Da die Suche nach unqualifizierten Namen des Argumenttyps im Bereich der Klasse beginnt
Bar
, wird sie im Bereich ihrer Basisklasse fortgesetzt, um dort ein Mitglied zu berücksichtigen. Und es wirdA::Foo::Foo
als Typname gefunden.Wenn Sie den globalen Typnamen verwenden möchten, qualifizieren Sie ihn einfach anhand seines umgebenden (globalen) Namespace.
Dies führt eine vollständig qualifizierte Suche in einem Bereich durch, in dem der Name der injizierten Klasse nicht angezeigt wird.
Für eine Folge "Warum" Frage siehe
quelle
struct Bar:: A::Foo::Foo::Foo::Foo::Foo {};
aber es gibt Kontexte, in denenA::Foo::Foo
der Konstruktor bezeichnet wird, und daher können Sie nicht so viele hinzufügen,Foo
wie Sie möchten. Dies ähnelt (aber mit einem völlig anderen Mechanismus) der Tatsache, dass Sie eine Funktion folgendermaßen aufrufenf
können :(************f)()
.Keine vollständige Antwort, nur Code, der anzeigt (da er kompiliert wird), dass
Bar
der nicht eingegeben wirdnamespace A
. Sie können sehen, dass es beim Erben vonA::Foo1
kein Problem gibt, dessen MehrdeutigkeitFoo
anders wäre, wenn diese VererbungBar
eintreten würdeA
.quelle