Could someone please help me understand why the following code does not compile (g++ 4.8). My understanding is that one could initialize a POD
#include <iostream>
#include <type_traits>
struct my_int
{
int val_;
};
struct B : public my_int
{
};
int main()
{
std::cout << std::is_pod<my_int>::value << std::endl;
std::cout << std::is_pod<B>::value << std::endl;
const my_int v = { 123 };
//const B v2 = { 123 }; // does not compile with g++ 4.8.
return 0;
}
Compilation is:
g++ -std=c++11 t.cxx
t.cxx: In function 'int main()':
t.cxx:24:21: error: could not convert '{123}' from '<brace-enclosed initializer list>' to 'const B'
const B v = { 123 };
^
EDIT:
Thanks to everyone answer I now understand the concept of aggregate initialisation. I missed the fact that aggregate could not have base class. Therefore my current implementation plans needs to be changed. I wanted to do something like:
template < typename T >
struct base_class
{
int val_;
};
struct MyInt : public base_class<int>
{
void Func1() {}
};
struct MyDouble : public base_class<double>
{
void Func2() {}
};
I'll rework the above code to avoid the use of subclass to introduce special member functions, while avoid code duplication.
Disclaimer
Take the following with a grain of salt as it is my interpretation of things. I am by no means an expert. (Also I have some doubts about the aggregate - initializer list relation which I stated here.)
Answer
As far as I can tell this is not possible because the aggregate initialization of v2 would be applied to the non aggregate class type B.
From this answer you can take that aggregates must not have a base class,
which makes B
a non aggregate and therefore not initializable by a brace enclosed initializer list.
On the other hand std::is_pod
might not do what you think it does because the POD definition has changed in C++11. Therefore, it does not give you a hint if the type that is a POD can be initialized with such an aggregate initializer.
Addition
I am mainly discussing aggregate initialization here, but the more general term for this is list initialization which is less restrictive. However, checking all the cases I found in the linked resource there is no possibility to do list initialization either because (following the resource's list of effects of an initializer list):
B
is not an aggregateB
is not a specialization of std::initializer_list
B
has no
B
is no reference typeB
cannot be copy-initialized from 123
and not direct-initialized because there is no constructor taking an intB
is not value-initialized because the initializer list ist not emptyIf 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