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.
The explicitly initialized elements of the aggregate include
the associated elements of each member M of C
for which M is designated by an identifier
in a designated-initializer-clause.
If the braced-init-list has an initializer-list
(possibly within a designated-initializer-list)
the explicitly initialized elements of the aggregate
include those for which an element of the initializer list
appertains to the aggregate element or to a subobject thereof (see below).
[Example 2: struct A {int a1, a2; };
struct B : A {int b; };
struct C : A {int a1; };
A v0 = A{1, .a2=2}; // error: initializer-clause appertains to non-static data member
B v1 = B{.a1=1, .b=2}; // the explicitly initialized elements are [A, B::b]
B v2 = B{.a1=1, .a2=2, .b=3}; // the explicitly initialized elements are [A, B::b]
B v3 = B{A{1, 2}, .b=3}; // the explicitly initialized elements are [A, B::b]
B v4 = B{A{}, .a2=1, .b=3}; // error: A initialized two different ways
C v5 = C{.a1=4}; // the explicitly initialized elements are [C::a1] — end example]
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.
[Example 4: struct A {int a; };
struct B : A {int b; };
struct C : B {int c; };
// the A element is initialized from {.a=1}
B x = B{.a=1};
// the B element is initialized from {.a=2, .b=3}// which leads to its A element being initialized from {.a=2}
C y = C{.a=2, .b=3, .c=4};
— end example]
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 9: 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 10: 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 11: 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.
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 16: 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 18: 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]