Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Virtual inheritance vs. non-default constructors

This code is rejected by (at least) MSVC, ICC, and GCC:

class A {
public:
    A( int ) {  }
};

class B: virtual public A {
public:
    //B(): A( -1 ) {  } // uncomment to make it compilable
    virtual void do_something() = 0;
};

class C: public B {
public:
    C(): A( 1 ) {  }
    virtual void do_something() {  }
};

int main() {
    C c;
    return 0;
}

on the basis of

error : no default constructor exists for class "A"
    class B: virtual public A {
                            ^
            detected during implicit generation of "B::B()" at line 14

Questions:

  1. If the code is indeed invalid, how exactly does this follow from the standard? AFAICT, 10.4/2 and 1.8/4 taken together imply that B cannot be a type of the most derived class, and therefore from 12.6.2/10 we have that B can never, ever call A's constructors. (The section numbers are for C++11.)

  2. If the code is valid, are compilers violating the standard by requiring the presence of constructors they could not possibly call? Note that not only they want to call A::A() from B::B(), but they want to do it while compiling C::C() (double weird).

P.S. This was originally asked on the ICC forum, but posted here due to not being limited to this compiler (and no details forthcoming).

like image 634
vpozdyayev Avatar asked Jul 27 '12 18:07

vpozdyayev


1 Answers

Clang shows the error as:

error: call to implicitly-deleted default constructor of 'B'
    C(): A( 1 ) {  }
    ^

12.1/5 says "A defaulted default constructor for class X is defined as deleted if [...] any [...] virtual base class [...] has class type M [...] and [...] M has no default constructor [...]."

like image 193
bames53 Avatar answered Oct 04 '22 15:10

bames53