Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using this pointer in initializer list

Tags:

c++

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?

like image 926
feverzsj Avatar asked Aug 07 '12 14:08

feverzsj


1 Answers

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&)
like image 168
ecatmur Avatar answered Nov 10 '22 21:11

ecatmur