In the following code, the compiler is requesting the base class X to be default constructible. However, if I remove the virtual keyword from the inheritance of the class Node, the access to the member m_x becomes, of course, ambiguous, but the default constructor for class X is no longer required.
What is the reason for that?
#include <iostream>
struct Apply
{
    template< typename T >
    struct Node : virtual T    // this line contains the virtual inheritance
    {
        template< typename ...Args>
        Node( Args... args )
            : T( args... )
        {}
    };
    template < typename ...BaseClasses>
    struct Inheritance;
    template < typename FirstBaseClass, typename ...OtherBaseClasses>
    struct Inheritance< FirstBaseClass, OtherBaseClasses... >   : FirstBaseClass
            , Inheritance< OtherBaseClasses... >
    {
        template< typename ...Args>
        Inheritance( Args... args )
            : FirstBaseClass( args... )
            , Inheritance< OtherBaseClasses... >( args... )
        {
        }
    };
};
template < >
struct Apply::Inheritance< >
{
    template< typename ...Args>
    Inheritance( Args... args ){}
};
struct X
{
    X(int i){}
    int m_x;
};
struct A : Apply::Node< X >
{
    A( int i )
        : Apply::Node< X >( i )
        , m_a( i )
    {
    }
    int m_a;
};
struct B : Apply::Node< X >
{
    B( int i )
        : Apply::Node< X >( i )
        , m_b( i )
    { }
    int m_b;
};
struct C : Apply::Node< X >
{
    C( int i )
        : Apply::Node< X >( i )
        , m_c( i )
    { }
    int m_c;
};
struct Example : Apply::Inheritance< A, B, C >
{
    Example( int i )
        : Apply::Inheritance< A, B, C >( i )
    { }
    void print( ) const
    {
        // this line needs the virtual inheritance
        std::cout << m_x << std::endl;
        std::cout << m_a << std::endl;
        std::cout << m_b << std::endl;
        std::cout << m_c << std::endl;
    }
};
int main()
{
    Example ex( 10 );
    ex.print( );
    return 0;
}
                The initialization ordering for a class goes like this [class.base.init]:
In a non-delegating constructor, initialization proceeds in the following order:
— First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
Your hierarchy is A --> Node<X> --> X, so the first thing to get initialized is the X, since it's a virtual base class. It's not specified in your mem-initializer, so the implicit default construction is inserted:
A( int i )
    : X() // <== implicit 
    , Node< X >( i )
    , m_a( i )
{
}
Since X isn't default constructible, you get that error. You can fix this with just explicitly providing the right thing:
A( int i )
    : X(i)
    , Node< X >( i )
    , m_a( i )
{
You don't have to worry about X being constructed twice, since virtual base classes are only constructed for the most derived class... which would be A and not Node<X>.
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