Facendo seguito a this question about multiple (virtual) inheritance, mi piacerebbe chiedere informazioni su un semplice MWE che rende g ++ 5.2.0 sconvolto mentre clang ++ 3.6.2 gestisce proprio bene, con nessuna lamentela tutto, anche con -Wall
e -Wextra
set. Quindi, ecco la MWE:eredità virtuale e l'inizializzazione uniforme in C++
class Z {};
class A : virtual Z { protected: A() {} };
class B : virtual Z { protected: B() {} };
class C : A, B { public: C() : A{}, B{} {} };
int main() { C c{}; return 0; }
differenza clang ++, g ++ lamenta come questo:
gccodd.c++: In constructor ‘C::C()’:
gccodd.c++:2:34: error: ‘A::A()’ is protected
class A : virtual Z { protected: A() {} };
^
gccodd.c++:4:39: error: within this context
class C : A, B { public: C() : A{}, B{} {} };
^
gccodd.c++:3:34: error: ‘B::B()’ is protected
class B : virtual Z { protected: B() {} };
^
gccodd.c++:4:39: error: within this context
class C : A, B { public: C() : A{}, B{} {} };
^
Sostituzione l'inizializzazione divisa nel costruttore di C con il vecchio modulo funziona bene e anche se sia clang ++ e g ++ sono felici con il seguente:
class C : A, B { public: C() : A(), B() {} };
Questo produce le due opzioni ovvie:
- Il codice viola lo standard in qualche modo, rendendo l'esito indefinito (vale a dire, qualsiasi risultato sarebbe accettabile).
- Uno dei due compilatori presenta un bug relativo all'inizializzazione uniforme e all'ereditarietà multipla + virtuale.
Se si trattasse di una questione di voto, (1) potrebbe vincere, perché ICPC 15.0.0 dice il seguente:
gccodd.c++(4): error #453: protected function "A::A()" (declared at line 2) is not accessible through a "A" pointer or object
class C : public virtual A, public virtual B { public: C() : A{}, B{} {} };
^
gccodd.c++(4): error #453: protected function "B::B()" (declared at line 3) is not accessible through a "B" pointer or object
class C : public virtual A, public virtual B { public: C() : A{}, B{} {} };
^
Quindi, è (1) o (2)? E se è il caso precedente, allora cosa c'è che non va nel mio MWE?
Sembra un bug. Non c'è motivo di pensare che ci sarebbe UB qui. –
VC++ 14.0 lo compila bene anche se IntelliSense si lamenta. – Fireho
GCC è bacato quando si tratta di [inizializzazione di aggregazione delle classi di base in un inizializzatore di mem] (http://coliru.stacked-crooked.com/a/8c60d42406381caa). – 0x499602D2