brace initialization for inherited pod
base_pod_t
is an aggregate and the initialization you're performing is aggregate initialization.
From §8.5.1 [dcl.init.aggr]
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).
2 When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause. ...
However, der_pod_t
is not an aggregate because it has a base class. It's a POD, and the same rules for list initialization do not apply. Now, when the compiler sees a non-empty braced-init-list it'll first search for a constructor that takes an initializer_list
. If none are found it then attempts to match other constructors of the class. Since der_pod_t
has no constructors that take a single int
as argument, the error occurs.
As of CPP 17 this is allowed with a slight twist that you need additional {} within the initializer list for each base class. Note in the below example how {1,2} are enclosed in "{}" and initialize i, j while "3" initializes derived k.
struct base_pod
{
int i, j;
};
struct der_pod : public base_pod
{
int k;
};
der_pod dp{ {1 , 2}, 3 };
This works on GCC version 7.3.0 (not sure about earlier versions) but fails on VS17(v 15.9.4) and VS17 with "/std:c++17" flag so be mindful of your compiler support/flags.
relevant change proposal is here