#include <iostream>
#include <type_traits>
struct base_pod_t {
unsigned x;
};
struct der_pod_t : public base_pod_t { };
int main()
{
std::cout << "base_pod_t is POD: " << std::is_pod<base_pod_t>::value << std::endl;
std::cout << "der_pod_t is POD: " << std::is_pod<der_pod_t>::value << std::endl;
base_pod_t b1 = {}; // OK
base_pod_t b2 = {3}; // OK
der_pod_t p1 = {}; // OK
// der_pod_t p2 = {4}; // ERROR!
}
Last line results in error. How can I brace initialize der_pod_t
with value?
It seems that even though it's a POD it tries to use constructor?
EDIT:
As @Praetorian and @dyb suggested it is a POD thus result of std::is_pod<der_pod_t>::value
is correct.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With