Saya memiliki kode berikut:
namespace A {
struct Foo {
int a;
};
}
struct Foo {
int b;
};
struct Bar : public A::Foo {
Bar(Foo foo) {
c = foo.b;
}
int c;
};
Kompiler C ++ mengeluh pada "c = foo.b" karena A :: Foo tidak memiliki anggota bernama b. Jika saya mengubah jenis parameter Bar dengan :: Foo berfungsi.
Pertanyaan saya adalah apa rasional di balik perilaku ini (saya kira itu ada hubungannya dengan fakta bahwa warisan membuat Bar memasuki ruang nama A tetapi saya tidak dapat menemukan dokumentasi untuk mendukung teori ini.
c++
inheritance
namespaces
language-lawyer
Vincent Le Ligeour
sumber
sumber
A
, yang dapat Anda lihat jika Anda membiarkanBar
mewarisi dari struct lain diA
. Maka tidak ada ambiguitas. Hal ini lebih seperti warisan menambahkan segala sesuatu dariA::Foo
keBar
termasuk resolusiFoo
untukA::Foo
. Maaf, saya tidak bisa mengungkapkannya dengan lebih tepat.Jawaban:
Setiap kelas menyuntikkan namanya sebagai anggota. Jadi Anda bisa memberi nama
A::Foo::Foo
. Ini disebut nama kelas yang disuntikkan.Karena pencarian nama yang tidak memenuhi syarat dari jenis argumen dimulai dalam lingkup kelas
Bar
, itu akan berlanjut ke dalam ruang lingkup kelas dasarnya untuk memperhitungkan setiap anggota di sana. Dan itu akan ditemukanA::Foo::Foo
sebagai nama tipe.Jika Anda ingin menggunakan nama tipe global, cukup kualifikasi dengan namespace sekitarnya (global).
Yang melakukan pencarian yang memenuhi syarat dalam lingkup di mana nama kelas yang disuntikkan tidak muncul.
Untuk pertanyaan "mengapa" tindak lanjut, lihat
sumber
struct Bar:: A::Foo::Foo::Foo::Foo::Foo {};
tetapi ada konteks di manaA::Foo::Foo
menunjuk konstruktor dan dengan demikian di sana Anda tidak dapat terus menambahkan sebanyak yangFoo
Anda inginkan. Ini mirip (tapi dengan mekanisme yang sama sekali berbeda) dengan fakta bahwa Anda dapat memanggil fungsif
seperti ini:(************f)()
.Bukan jawaban yang lengkap, hanya kode yang menunjukkan (karena mengkompilasi) yang
Bar
tidak memasukkannamespace A
. Anda dapat melihat bahwa ketika mewarisi dariA::Foo1
sana tidak ada masalah dengan ambiguitasFoo
yang akan berbeda jika warisan ini memungkinkanBar
masukA
.sumber