I try to use value-initialization for members with value-initialization for constructors (I don't know if I really use the good terms...)
So... When I define:
struct A
{
int a_;
};
I'm able to use:
A a{5};
assert(m.a_==5);
However, if I want to use the member brace initializer AND an initialization-list constructor
struct B
{
int b_ {1};
};
This doesn't 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, concept-wise? Many thanks!
Under C++11 rules, B
is not an aggregate type. C++11 [dcl.init.aggr]/1:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
B
only has a default constructor, and thus cannot be initialized from the braced-initializer-list {2}
.
C++14 allows brace-or-equal-initializers for non-static data members in an aggregate. N4140 [dcl.init.aggr]/1:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
With fairly straight-forward semantics: fields for which there is no initializer specified are initialized from their brace-or-equal-initializer, if any, and otherwise initialized with {}
[dcl.init.aggr]/7:
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal-initializer, from an empty initializer list (8.5.4).
Your program is thus valid C++14 (DEMO). Essentially, the prohibition of brace-or-equal-initializers in C++11 was a mistake that C++14 corrected.
If 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