问题
struct Point {
int x = 0;
int y = 10;
};
Point p = {1,};
p.x == 1; // true
p.y == 10; // is this true?
According to the standard missing elements in initializer list are value initialized, so y
should be int()
or 0
, but it doesn't seem to say what happen in the situation of Non-static Data Member Initializer.
Edit: According to the answer, apparently this is invalid c++11, I would like to know the situation in c++1y.
回答1:
C++98, C++03
Non-static data member initialisers (NSDMIs) do not exist; the question is inapplicable.
C++11
Well, first of all, this initialisation is invalid because your type is not an aggregate:
[C++11: 8.5.1/1]:
An aggregate is an array or a class (Clause 9) with 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).
So, aggregate initialisation can't be performed here; a constructor taking an std::initializer_list
would be your only way to use that initialisation syntax ([C++11: 8.5.4/3]
), but you don't have one of those either.
Consequently, the entire premise of the question is flawed: it is not possible to get yourself into this state.
C++1y
In the upcoming version of the standard, the definition of aggregates has been relaxed to allow your type to be deemed an aggregate (as long as both of those members stay public
!):
[n3936: 8.5.1/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).
Following on from this, there's a rule that guarantees the result you're looking for:
[n3936: 8.5.1/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). [ Example:struct S { int a; const char* b; int c; int d = b[a]; }; S ss = { 1, "asdf" };
initializes
ss.a
with1
,ss.b
with"asdf"
,ss.c
with the value of an expression of the formint{}
(that is,0
), andss.d
with the value ofss.b[ss.a]
(that is,’s’
), and instruct X { int i, j, k = 42; }; X a[] = { 1, 2, 3, 4, 5, 6 }; X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
a
andb
have the same value —end example ]
回答2:
(Answer valid in C++1y, only!)
According to paragraph #7 of section "8.5.1 Aggregates" (Working Draft N3691 Date: 2013-05-16)
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-equalinitializer, from an empty initializer list (8.5.4).
And below the quote there is an example
[ Example: struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
initializes ss.a with 1, ss.b with "asdf", ss.c
with the value of an expression of the form int{} (that is, 0), and
ss.d with the value of ss.b[ss.a] (that is, ’s’),
So in your example p.y will be initialized by 10.
来源:https://stackoverflow.com/questions/24043577/partial-aggregate-initialization-and-non-static-data-member-initializer