Aggregate initialization of a derived class

The following code does not compile with either Visual Studio2017 or online GDB. I expected it to compile since the iterator is just a class with types and it is inherited from publicly. Is this not allowed or does not work in VS2017?

template<typename T> struct Gen : public std::iterator<std::input_iterator_tag, T> { T value; }; int main() { Gen<int> g = Gen<int>{ 10 }; // this doesnt Gen<int> g2 = Gen<int>{ {}, 10 }; // neither does this } 

Error

Error C2440 'initializing': cannot convert from 'list of initializers' to 'Gen'

+5
source share
1 answer

what

 Gen<int> g = Gen<int>{ 10 }; 

trying to make a call to the nonexistent constructor Gen<int>(int) . What you want to do is initialize aggregates whose syntax is:

 Gen<int> g = { {}, 10 }; 

And it only works with C ++ 17 for derived types:

If the initializer clause is a nested init-list bit (which is not an expression), the corresponding element of the array / class element / public base (since C ++ 17) is initialized from this clause: aggregate initialization is recursive.


For more information, unit initialization is defined in the following standard sections.

[dcl.init.list]/3

  1. An initialization list of an object or link of type T is defined as follows:
    3.1 If the list of init bits contains a list of designated initializers, T shall be an aggregate class.

and

[dcl.init.aggr]/1

An aggregate is an array or class (section 12) using 1.1 there are no custom, explicit or inherited constructors (15.1),
1.2 no private or protected non-static data (section 14),
1.3 there are no virtual functions (13.3) and
1.4 there are no virtual, private or protected base classes (13.1).

Because it inherits from std::iterator<std::input_iterator_tag, T> .

+10
source

Source: https://habr.com/ru/post/1274893/


All Articles