MSVC, Dentang dan GCC tidak setuju pada kode ini:
struct Base { int x; };
struct Der1 : public Base {};
struct Der2 : public Base {};
struct AllDer : public Der1, public Der2 {
void foo() {
Der1::Base::x = 5;
}
};
GCC:
<source>: In member function 'void AllDer::foo()':
<source>:10:21: error: 'Base' is an ambiguous base of 'AllDer'
10 | Der1::Base::x = 5;
| ^
Compiler returned: 1
Dentang memberikan kesalahan yang sama, dan MSVC tidak memberikan kesalahan.
Siapa di sini?
Saya kira ini tercakup dalam [class.member.lookup] , tetapi saya mengalami kesulitan memahami apa yang ingin saya sampaikan kepada saya untuk kasus ini. Silakan mengutip bagian-bagian yang relevan dan jika mungkin jelaskan dalam bahasa Inggris.
PS: Terinspirasi oleh pertanyaan ini. Mengapa Referensi ke Kelas Dasar ambigu dengan :: -operator melalui kelas turunan?
PPS: Sebenarnya keraguan saya adalah apakah Der1::Base
merujuk pada tipe, apakah itu Base
(dan kemudian Der2::Base
adalah tipe yang sama persis), atau ke subobyek. Saya yakin itu yang pertama, tetapi jika ini yang terakhir maka MSVC akan benar.
c++
language-lawyer
multiple-inheritance
diamond-problem
qualified-name
idclev 463035818
sumber
sumber
::Base
, tetapi pertanyaan sebenarnya tampaknya sedikit berbeda di sini. Ada dua sub-jenis objekBase
, dan keduanya memilikiBase::x
anggota.Jawaban:
Untuk menjawab pertanyaan dalam judul, ya,
Derived1::Base
referensi nama kelas-disuntikkan [class.pre]Base
dan begitu jugaDerived2::Base
. Keduanya merujuk ke kelas::Base
.Sekarang, jika
Base
akan memiliki statis anggotax
, maka pencarian dariBase::x
akan ambigu. Hanya ada satu.Masalah dalam contoh ini adalah bahwa itu
x
adalah anggota non-statis, danAllDer
memiliki dua anggota tersebut. Anda dapat memisahkan akses semacam itux
dengan menetapkan kelas dasar yang tidak ambiguAllDer
yang hanya memiliki satux
anggota.Derived1
adalah kelas dasar yang tidak ambigu, dan memiliki satux
anggota, sehinggaDerived1::x
secara jelas menentukan yang mana dari duax
anggota yangAllDer
Anda maksud.Base
juga hanya memiliki satux
anggota, tetapi itu bukan basis yang jelasAllDer
. Setiap instance dariAllDer
memiliki dua sub-objek bertipeBase
. KarenaBase::x
itu ambigu dalam contoh Anda. Dan karenaDerived1::Base
hanya nama lain untukBase
ini, ini tetap ambigu.[class.member.lookup] menentukan yang
x
dicari dalam konteks specifier nama-bersarang, sehingga harus diselesaikan terlebih dahulu. Kami memang mencariBase::x
, bukanDerived1::x
, karena kami mulai dengan menetapkanDerived1::Base
sebagaiBase
. Bagian ini berhasil, hanya ada satux
diBase.
Catatan 12 di [class.member.lookup] yang secara eksplisit memberi tahu Anda bahwa menggunakan pencarian nama yang tidak ambigu mungkin masih gagal ketika ada beberapa sub-proyek dengan nama yang sama.D::i
pada contoh itu pada dasarnya adalah milik AndaBase::x
.sumber
template <typname A,typename B> struct foo : A,B
dengan beberapa kode yang dibuat untuk mengakses anggota dari basisA
danB
. Dalam kasus seperti itu saya ingin mendapatkan kesalahanAlasan Anda dapat merujuk ke nama kelas sebagai anggota kelas adalah karena cpp alias untuk penggunaan yang mudah, seolah-olah Anda menulis
using Base = ::Base;
di dalam Base.Masalah yang Anda hadapi adalah bahwa
Der1::Base
adalahBase
.Jadi, ketika Anda menulis
Der1::Base::x
, itu sama denganBase::x
.sumber
using
ditulis dalam standar, dan saya pikir itulah kunci untuk menafsirkan apa yang dikatakan ungkapan itu.cl /c /Wall /WX /Od /MDd /Za /permissive- /std:c++17 main.cpp
sebagai baris perintahnya, saya mendapatkanmain.cpp(7): error C2597: illegal reference to non-static member 'A::x'