Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting constructors of virtual base classes

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?

like image 343
Fabian Knorr Avatar asked Oct 06 '15 10:10

Fabian Knorr


1 Answers

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.

like image 144
sergej Avatar answered Oct 13 '22 12:10

sergej