struct T
{
int a;
};
struct C
{
T& r;
C(T& v) : r(v) {}
};
struct E : T
{
T& r;
E(T const& v) : r(*this), T(v) {} // ok
};
struct F : C, T // base order doesn't matter here
{
//F(T const& v) : C(*this), T(v) {} // error : C::r is not initialized properly
F(T const& v) : C(*static_cast<T*>(this)), T(v) {} // ok
//F(T const& v) : C(static_cast<T&>(*this)), T(v) {} // ok
};
int main()
{
T v;
F f(v);
f.r.a = 1;
}
Although using this pointer in initializer list could be problem, but I've never expected this happened to PODs and may be simply fixed by explicit cast; Is this some compiler bug or std related problem?
The code is ambiguous.
For constructing the C
base of F
, the context is direct-initialization, so 13.3.1.3 applies:
c++11
13.3.1.3 Initialization by constructor [over.match.ctor]
For direct-initialization, the candidate functions are all the constructors of the class of the object being initialized.
The implicitly-declared copy constructor is included, per 12.8:8.
The candidates for the constructor of C
are C(T &)
and (the default copy constructor) C(const C &)
, by parameter list (F)
. In both cases we have a reference binding (13.3.3.1.4) followed by a derived-to-base Conversion (13.3.3.1), with an additional cv-qualification adjustment in the latter case, giving overall rank of Conversion in both cases.
Since C
and T
are both base classes of F
, but are distinct types and neither is a base class of the other, none of the clauses in 13.3.3.2:3 nor 13.3.3.2:4 apply and conversion sequences are indistinguishable.
Indeed, gcc-4.5.1 rejects the code with:
prog.cpp: In constructor 'F::F(const T&)':
prog.cpp:20:34: error: call of overloaded 'C(F&)' is ambiguous
prog.cpp:9:5: note: candidates are: C::C(T&)
prog.cpp:7:1: note: C::C(const C&)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With