-1

I want to initialize a class B that is a subclass of A by list-initialization (https://en.cppreference.com/w/cpp/language/list_initialization)

However, it does not work like this:

struct A {
   int x;
};

struct B : public A {
};

int main()
{
   A a{ 1 }; // compiles
   B b{ 2 }; // doesn't compile
}

Is there a way to initialize instances of B through list-initialization?

Essentially, I want to intitialize an instance of B without declaring any constructor.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Urquhart
  • 129
  • 10
  • Do you want to keep `B` as being an aggregate? – NathanOliver Aug 02 '22 at 14:25
  • @NathanOliver I would prefer so. Essentially, I want to initialize the subclass with values without declaring any constructor. I updated the question to make this clearer. – Urquhart Aug 02 '22 at 14:30
  • 2
    "*Is there a way to initialize instances of B through list-initialization?*" Use c++17. – 康桓瑋 Aug 02 '22 at 14:31
  • Dupe: [Why can I not brace initialize a struct derived from another struct?](https://stackoverflow.com/questions/16983539/why-can-i-not-brace-initialize-a-struct-derived-from-another-struct) – Jason Aug 02 '22 at 14:53

1 Answers1

5

The problem is that you are using a C++ compiler that compiles your program based on the C++ Standard before the C++ 17 Standard.

Before the C++ 17 Standard aggregates may not contain base classes.

So use the compiler option that sets at least the specification of the C++ 17 Standard.

According to the C++ 14 Standard (8.5.1 Aggregates)

1 An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

Starting from the C++ 17 Standard aggregates are allowed to have base classes (11.6.1 Aggregates)

1 An aggregate is an array or a class (Clause 12) with

(1.1) — no user-provided, explicit, or inherited constructors (15.1),

(1.2) — no private or protected non-static data members (Clause 14),

(1.3) — no virtual functions (13.3), and

(1.4) — no virtual, private, or protected base classes (13.1).

Pay also attention to that there is a difference according to aggregates in the C++17 and the C++20 Standards. For example in C++ 17 you are allowed to declare a constructor for an aggregate with the specifier default.

That is this program

struct A {
   int x;
};

struct B : public A {
    B() = default;
};

int main()
{
   A a{ 1 }; 
   B b{ 2 }; 
}

is valid according to the C++ 17 Standard and is invalid according to the C++20 Standard.

But if you will declare the constructor with the specifier explicit

struct B : public A {
   explicit  B() = default;
};

then the program will not be valid even according to the C++ 17 Standard.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Apparently, the compiler developers and I agree that it should be possible to instantiate sublcasses like this :D thanks for the quick response, it worked! – Urquhart Aug 02 '22 at 14:36