c++inheritanceconstructorc++14

C++14: Inheriting constructors with "using" AND defining new constructors yields C2512 (no appropriate default constructor available)


In C++, you can inherit all constructors of a base class by writing using Baseclass::Baseclass

My Baseclass has both a default constructor and another one that takes an int argument, even though that one doesn't really matter in this case.

But for reasons I don't understand the inherited default constructor somehow goes 'missing' the moment I try to add my own constructor to the derived class. Why is that and what's the best solution to circumvent this?

Consider the following code snippet:

#include <iostream>
#include <string>
using std::cout;

struct Base
{
  Base() {};
  Base(int i)
  {
    cout << i << " was called";
  };
};

struct GoodDaughter : public Base
{
  using Base::Base;
};

struct EvilSon : public Base
{
  using Base::Base;

  EvilSon(std::string q) {}; //define ANOTHER constructor
};

void testFamily()
{
  Base b;
  GoodDaughter g1; //compiles
  EvilSon e1;      //somehow doesn't compile, complains about no default constructor existing


  GoodDaughter g2(1); //compiles
  EvilSon e2(1);      //compiles, which means that other constructor still got inherited.
}

The error message is:

<source>(30): error C2512: 'EvilSon': no appropriate default constructor available
<source>(19): note: see declaration of 'EvilSon'

I'm using the latest version of MSVC 19. Some People found out that other compilers, such as gcc, did not give that error


Solution

  • I quote from here the comment by Phil Christensen who explains the difference between c++11/14 (where it does not compile) and later standards in the msvc compiler:

    The reason it does not work in C++11/14 is because of the wording in [class.inhctor]/3, calls out constructors with no parameters:

    For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters […], a constructor is implicitly declared with the same constructor characteristics […]

    In C++17, the [class.inhctor] section was removed from the standard, and the wording for inheriting constructors was significantly reworked by p0136r1.

    It is odd that the other major compilers support it in C++11/14 though, I am scanning through some of the related sections in the standard to see if there is something I am missing that adds to this or would affect the behavior.