Uniform and value initialization

I am trying to use initialization initialization for members with value initialization for constructors (I don't know if I really use good terms ...)

So ... When I define:

struct A { int a_; }; 

I can use:

 A a{5}; assert(m.a_==5); 

However, if I want to use the brace element initializer and the initialization list constructor

 struct B { int b_ {1}; }; 

This does not compile (C ++ 14: http://ideone.com/MQ1FMU ):

 B b{2}; 

Here is the error:

 prog.cpp:19:7: error: no matching function for call to 'B::B(<brace-enclosed initializer list>)' B b{2}; ^ prog.cpp:19:7: note: candidates are: prog.cpp:10:8: note: constexpr B::B() struct B ^ prog.cpp:10:8: note: candidate expects 0 arguments, 1 provided prog.cpp:10:8: note: constexpr B::B(const B&) prog.cpp:10:8: note: no known conversion for argument 1 from 'int' to 'const B&' prog.cpp:10:8: note: constexpr B::B(B&&) prog.cpp:10:8: note: no known conversion for argument 1 from 'int' to 'B&&' 

What is the difference conceptually? Thank you very much!

+6
source share
1 answer

According to C ++ 11 rules, B not an aggregate type. C ++ 11 [dcl.init.aggr] / 1:

An aggregate is an array or class (section 9) without constructors provided by the user (12.1), without elements with alignment or equal for non-static data elements (9.2) there are no private or protected non-static data (section 11), there are no base classes (section 10) and there are no virtual functions (10.3).

B has only the default constructor and therefore cannot be initialized from the braced-initializer-list {2} list.

C ++ 14 allows parenthesis initializers or equal for non-static data elements in the aggregate. N4140 [dcl.init.aggr] / 1:

An aggregate is an array or class (section 9) without constructors provided by the user (12.1), without private or protected non-static data elements (section 11), without base classes (section 10) and without virtual functions (10.3).

With fairly straightforward semantics: fields for which there is no specified initializer are initialized from their logical or equal-initializer, if any, and are otherwise initialized with {} [dcl.init.aggr] / 7:

If there are fewer initializer proposals in the list than in the aggregate, then each member that is not explicitly initialized should be initialized from its element with an equal-equal-initializer or, if there are no brackets or equal to -initializer from the empty initializer list (8.5.4) .

So your program is valid C ++ 14 ( DEMO ). In fact, the ban on alignment-alignment in C ++ 11 was a bug that C ++ 14 fixed.

+2
source

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


All Articles