c++constructorc++17derived-class

Calling the ctor of Derived class with the parameters of ctor off the Base class


Browsing my code I found a part which - I thought - should be a compile time error, but in reality in compiles and runs fine. A simplified version is:

class Base
{
public:
   Base(int i)
   {}
};


class Derived : public Base
{
public:
   //using Base::Base;
};


int main()
{
    Derived obj{ 5 };
}

Checking the code snippet in cppinsights, for the line inside main it generates Derived obj = {Base(5)}; when using c++17 or newer and does not compile with c++14 or older. In c++14 if I uncomment //using Base::Base; then the code compiles. This using here is available since C++11 I believe. In this case cppinsights generates Derived obj = Derived{5};. I can understand the meaning of it. My questions are

  1. Why does the original code compiles with c++17. What is name of the feature?
  2. What does {Base(5)}; mean? What are the curly brackets are used for?
  3. Does it have anything to do with using Base::Base; or they are completely different.

Thank you for your help!

EDIT1: I changed the main() function to the lines below, just to show what cppinsights "creates" from it

int main()
{
    Derived obj1{ 5 }; // OK. cppinsights: Derived obj1 = {Base(5)};
    Derived obj2 = {Base(5)}; // OK. cppinsights: {Base(Base(5))};
    //Derived obj3 = Base{5}; // error: no viable conversion from 'Base' to 'Derived'
}

Solution

  • Let's start with the second question.

    Derived obj{ 5 }; is the list-initialization syntax. The first (and only) expression on that list is used to initialize the Base member, which requires one conversion (from int to Base).

    Now, since C++17 Derived is an aggregate, which means that the list-initialization syntax now uses aggregate initialization. In C++14, the (public) base class prevented Derived from being an aggregate.

    In C++14, the using statement allowed the Base ctors to participate in overload resolution when constructing a Derived object. Base::Base(int) obviously wins the overload resolution for Derived{5}.