screwnut
screwnut

Reputation: 1383

Can I instantiate a struct through its base's default constructor?

Is it at all possible to have the second instantiation work somehow? I've tried combinations of using and = default but to no avail.

struct A
{
    int i;
};

struct B : A
{};

A a{11}; // This works.
B b{22}; // "No matching constructor".

Upvotes: 1

Views: 92

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311048

According to the C++ 2014 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).

However According to the C++ 2017 Standard (8.6.1 Aggregates):

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

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

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

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

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

As you can see, the C++ 2017 Standard removes the restriction that aggregates shall not have base classes. So the code will not be compiled by a compiler that does not support the C++ 2017 Standard.

You need to declare explicitly a constructor that excepts an argument for the class B yourself.

Upvotes: 4

user4581301
user4581301

Reputation: 33952

That's not a constructor for A. That's aggregate initialization.

Anyway, you are doomed. While B is-a A, there is no way to pass initialization through B to A without a constructor. There may be some voodoo and witchcraft to make it look like you are initializing A through B, but it would be better to just write some nice, clean code like a B constructor that initializes A

struct B : A
{
    B(int val):A{val}
    {
    }
};

Now obviously B has a constructor and

B b{22};

is valid.

Upvotes: 1

Related Questions