for a class, the direct base classes in declaration order,
followed by the direct non-static data members ([class.mem])
that are not members of an anonymous union, in declaration order.
When an aggregate is initialized by an initializer list
as specified in [dcl.init.list],
the elements of the initializer list are taken as initializers
for the elements of the aggregate.
If the initializer list is
a brace-enclosed designated-initializer-list,
the aggregate shall be of class type,
the identifier in each designator
shall name a direct non-static data member of the class, and
the explicitly initialized elements of the aggregate
are the elements that are, or contain, those members.
If the initializer list is a brace-enclosed initializer-list,
the explicitly initialized elements of the aggregate
are those for which an element of the initializer list
appertains to the aggregate element or to a subobject thereof (see below).
If that initializer is of the form
=assignment-expression
and
a narrowing conversion ([dcl.init.list]) is required
to convert the expression, the program is ill-formed.
Otherwise,
the aggregate element is copy-initialized
from a brace-enclosed initializer-list
consisting of all of the initializer-clauses
that appertain to subobjects of the aggregate element,
in the order of appearance.
If an initializer is itself an initializer list,
the element is list-initialized, which will result in a recursive application
of the rules in this subclause if the element is an aggregate.
struct S {int a; constchar* 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').
The destructor for each element of class type
other than an anonymous union member
is potentially invoked ([class.dtor])
from the context where the aggregate initialization occurs.
The number of elements ([dcl.array]) in an array of unknown bound
initialized with a brace-enclosed initializer-list
is the number of explicitly initialized elements of the array.
int x[]={1, 3, 5};
declares and initializes
x
as a one-dimensional array that has three elements
since no size was specified and there are three initializers.
A default member initializer does not determine the bound for a member
array of unknown bound.
Since the default member initializer is
ignored if a suitable mem-initializer is present ([class.base.init]),
the default member initializer is not
considered to initialize the array of unknown bound.
[Example 6: struct S {int y[]={0}; // error: non-static data member of incomplete type};
— end example]
Static data members,
non-static data members of anonymous union members,
and
unnamed bit-fields
are not considered elements of the aggregate.
[Example 7: struct A {int i;
staticint s;
int j;
int:17;
int k;
} a ={1, 2, 3};
Here, the second initializer 2 initializes
a.j
and not the static data member
A::s, and the third initializer 3 initializes a.k
and not the unnamed bit-field before it.
If a member has a default member initializer
and a potentially-evaluated subexpression thereof is an aggregate
initialization that would use that default member initializer,
the program is ill-formed.
[Example 8: struct A;
extern A a;
struct A {const A& a1 { A{a,a}}; // OKconst A& a2 { A{}}; // error};
A a{a,a}; // OKstruct B {int n = B{}.n; // error};
— end example]
When initializing a multidimensional array,
the
initializer-clauses
initialize the elements with the last (rightmost) index of the array
varying the fastest ([dcl.array]).
int x[2][2]={3, 1, 4, 2};
initializes
x[0][0]
to
3,
x[0][1]
to
1,
x[1][0]
to
4,
and
x[1][1]
to
2.
On the other hand,
float y[4][3]={{1}, {2}, {3}, {4}};
initializes the first column of
y
(regarded as a two-dimensional array)
and leaves the rest zero.
Each initializer-clause in
a brace-enclosed initializer-list
is said to appertain
to an element of the aggregate being initialized or
to an element of one of its subaggregates.
Considering the sequence of initializer-clauses,
and the sequence of aggregate elements
initially formed as the sequence of elements of the aggregate being initialized
and potentially modified as described below,
each initializer-clause appertains to
the corresponding aggregate element if
the initializer-clause is an expression and
an implicit conversion sequence can be formed
that converts the expression to the type of the aggregate element, or
the aggregate element is an aggregate that itself has no aggregate elements.
Otherwise,
the aggregate element is an aggregate and
that subaggregate is replaced in the list of aggregate elements by
the sequence of its own aggregate elements, and
the appertainment analysis resumes with
the first such element and the same initializer-clause.
In
struct S1 {int a, b; };
struct S2 { S1 s, t; };
S2 x[2]={1, 2, 3, 4, 5, 6, 7, 8};
S2 y[2]={{{1, 2},
{3, 4}},
{{5, 6},
{7, 8}}};
x and y have the same value.
float y[4][3]={{1, 3, 5},
{2, 4, 6},
{3, 5, 7},
};
is a completely-braced initialization:
1, 3, and 5 initialize the first row of the array
y[0],
namely
y[0][0],
y[0][1],
and
y[0][2].
Likewise the next two lines initialize
y[1]
and
y[2].
The initializer ends early and therefore
y[3]'s
elements are initialized as if explicitly initialized with an
expression of the form
float(),
that is, are initialized with
0.0.
In the following example, braces in the
initializer-list
are elided;
however the
initializer-list
has the same effect as the completely-braced
initializer-list
of the above example,
float y[4][3]={1, 3, 5, 2, 4, 6, 3, 5, 7};
The initializer for
y
begins with a left brace, but the one for
y[0]
does not,
therefore three elements from the list are used.
Likewise the next three are taken successively for
y[1]
and
y[2].
The initializer for an empty subaggregate is needed
if any initializers are provided for subsequent elements.
[Example 13: struct S {} s;
struct A {
S s1;
int i1;
S s2;
int i2;
S s3;
int i3;
} a ={{}, // Required initialization0,
s, // Required initialization0}; // Initialization not required for A::s3 because A::i3 is also not initialized — end example]
When a union is initialized with an initializer list,
there shall not be more than one
explicitly initialized element.
[Example 15: union u {int a; constchar* b; };
u a ={1};
u b = a;
u c =1; // error
u d ={0, "asdf"}; // error
u e ={"asdf"}; // error
u f ={.b ="asdf"};
u g ={.a =1, .b ="asdf"}; // error — end example]