Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 467
DRman Avatar asked Oct 15 '25 16:10

DRman


1 Answers

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.

like image 50
463035818_is_not_an_ai Avatar answered Oct 18 '25 07:10

463035818_is_not_an_ai