6

Virtual base classes are initialized in the most derived class, so my guess is that inheriting the constructor of the base class should work as well:

struct base {
    base(int) {}
};

struct derived: virtual base {
    using base::base;
};

derived d(0);

However, this fails to compile with GCC 5.2.0, which tries to find base::base(), but works fine with Clang 3.6.2. Is this a bug in GCC?

Fabian Knorr
  • 3,134
  • 3
  • 20
  • 32

1 Answers1

6

This is gcc bug 58751 "[C++11] Inheriting constructors do not work properly with virtual inheritance" (aka: 63339 "using constructors" from virtual bases are implicitly deleted"):

From the 58751 description:

In the document N2540 it states that:

Typically, inheriting constructor definitions for classes with virtual bases will be ill-formed, unless the virtual base supports default initialization, or the virtual base is a direct base, and named as the base forwarded-to. Likewise, all data members and other direct bases must support default initialization, or any attempt to use a inheriting constructor will be ill-formed. Note: ill-formed when used, not declared.

Hence, the case of virtual bases is explicitly considered by the committee and thus should be implemented.

Workaround borrowed from the bug report:

struct base {
    base() = default;  // <--- add this
    base(int) {}
};

According to the bug report, in this cases the constructor base::base(int) is called by the implicitly generated constructor derived::derived(int).

I have checked that your code does not compile. But this does and it calls the base::base(int) constructor.

sergej
  • 17,147
  • 6
  • 52
  • 89
  • Of course this still doesn't work if `base` cannot be default-constructed... So it appears that the only way around this is manually re-defining the constructors in all derived classes. – Fabian Knorr Oct 06 '15 at 11:14