Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::is_pod vs subclassing

Tags:

c++

c++11

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.

like image 636
malat Avatar asked Sep 20 '13 16:09

malat


1 Answers

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):

  • the initializer list is not empty
  • B is not an aggregate
  • B is not a specialization of std::initializer_list
  • B has no
    • constructor taking an initializer list
    • constructor fitting the signature of the list
  • B is no reference type
  • B cannot be copy-initialized from 123 and not direct-initialized because there is no constructor taking an int
  • B is not value-initialized because the initializer list ist not empty
like image 187
Nobody moving away from SE Avatar answered Oct 25 '22 20:10

Nobody moving away from SE