Search code examples
c++virtual

Virtual inheritance and default constructor


Here is a sample code :

#include <iostream>
#include <utility>
using namespace std;

struct D;
struct X {};
struct Y {};


template <typename T>
struct A    // A : ASequencialPlanningJobQueueFactory
{
    A() = delete;
    A(T* t) { cout << "A constructor" << endl; }
};

struct B : A<B>    // B : AThermostatedRotorJobQueueFactory
{
    B(B* b, const X& x, const Y& y) : A(b) { cout << "B constructor" << endl; }
};

template <typename T>
struct C : T    // C : PlanningJobQueueFactoryStub
{
    template <typename... Args>
    C(Args&&... args) : T(std::forward<Args>(args)...) { cout << "C constructor" << endl; }
};

struct D : C<B>     // D: ThermostatedRotorJobQueueFactoryStub
{
    D(const X& x, const Y& y) : C(this, x, y) { cout << "D constructor" << endl; }
};

int main()
{
    X x;
    Y y;

    D d(x, y);
    cout << "----------" << endl;

    return 0;
}

If I add a virtual inheritance to B, as in :

struct B : virtual A<B>
{
    B(B* b, const X& x, const Y& y) : A(b) { cout << "B constructor" << endl; }
};

the code doesn't compile anymore. WHY ?

It was long to find the error. Clang and gcc were not very helpful...


Solution

  • With virtual inheritance, the most derived class should call virtual base constructor, so:

    struct D : C<B>     // D: ThermostatedRotorJobQueueFactoryStub
    {
        D(const X& x, const Y& y) : A(this), C(this, x, y) { cout << "D constructor" << endl; }
    };
    

    But that is also true for C<B>:

    template <>
    struct C<B> : B
    {
        template <typename... Args>
        C(Args&&... args) : A(this), B(std::forward<Args>(args)...) {
            cout << "C constructor" << endl;
        }
    };