Enable default initializer list constructor

I find that modern C ++ initializer lists are very useful for initializing objects to remove the need to define your own constructor:

struct point { float coord[3]; }; point p = {1.f, 2.f, 3.f}; // nice ! 

However, this does not work when my class inherits from another class:

 template<typename T> class serializable { protected: serializable() = default; ... // other stuff } struct point : public serializable<point> { float coord[3]; }; point p = {1.f, 2.f, 3.f}; // Doesn't work :( 

I tried adding point() = default; to my point class, but that didn't work either. How can I initialize a point using a list of initializers?

+7
c ++ inheritance c ++ 11 list-initialization initializer-list
source share
1 answer

Your original case was based on aggregate initialization [dcl.init.list]:

An initialization list of an object or link of type T is defined as follows:
...
- Otherwise, if T is an aggregate, aggregate initialization is performed

If aggregated and aggregated initialization is [dcl.init.aggr], the focus is:

An aggregate is an array or class (section 9) without any constructors provided by the user (12.1), without personal or (section 11), there are no base classes (section 10), and there are no virtual functions (10.3).

When an aggregate is initialized with a list of initializers, as specified in 8.5.4, the elements of the list of initializers are taken as initializers for members of the population, increasing the index or order of members. each member is initialized with a copy from the corresponding initializer clause.

But now, since point has a base class ( serializable<point> ), point no longer an aggregate and no longer supports aggregate initialization.

The solution is to simply provide such a constructor for initializing point :

 struct point : public serializable<point> { template <typename... T> point(T... ts) : coord{ts...} { } float coord[3]; }; 
+8
source share

All Articles