c++c++17language-lawyervirtual-inheritance

When should constructor of virtual base class be called?


Consider the following example:

struct Grandpa {
    Grandpa(int x) {}
};

struct Dad : Grandpa {
    Dad(int y) : Grandpa(15) {}
};

struct Son : Dad {
    Son(int z) : Dad(z) {}
};

int main () {
    Son s(10);
}

It compiles just fine, however, if I make Grandpa not just baseclass of Dad, but virtual baseclass:

struct Grandpa {
    Grandpa(int x) {}
};

struct Dad : virtual Grandpa {
    Dad(int y) : Grandpa(15) {}
};

struct Son : Dad {
    Son(int z) : Dad(z) {}
};

int main () {
    Son s(10);
}

This code doesn't compile! Compilation fails with

example.cpp: In constructor ‘Son::Son(int)’:
example.cpp:12:27: error: no matching function for call to ‘Grandpa::Grandpa()’
   12 |         Son(int z) : Dad(z) {}

What are the rules, according to C++ standard, regarding virtual baseclasses' constructor calls?


Solution

  • As Pete Becker in comments, and Chris Dodd in answers have pointed out:

    The constructor of a virtual base class is called from the constructor of the most derived class, in this case, from the constructor of Son. Since there is no default constructor for Grandpa, the constructor for Son needs to explicitly call the Grandpa constructor.

    The closest thing that corresponds to this answer in C++ standard I found is: 15.6.2 Initializing bases and members # 13.1

    What it says, is that order of which constructor is called is first virtual baseclasses (even non-direct baseclasses!!), and then direct non-virtual baseclassses. So compiler, after not seeing call to Grandpa constructor in Son constructor, doesn't bother calling Dad constructor to find call to Grandpa constructor there: compiler decides to fail compilation, which is OK for compiler, according to standard.