504 lines
21 KiB
Markdown
504 lines
21 KiB
Markdown
[dcl.init.aggr]
|
||
|
||
# 9 Declarations [[dcl]](./#dcl)
|
||
|
||
## 9.5 Initializers [[dcl.init]](dcl.init#aggr)
|
||
|
||
### 9.5.2 Aggregates [dcl.init.aggr]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5475)
|
||
|
||
An [*aggregate*](#def:aggregate "9.5.2 Aggregates [dcl.init.aggr]") is an array or a class ([[class]](class "11 Classes")) with
|
||
|
||
- [(1.1)](#1.1)
|
||
|
||
no user-declared or inherited constructors ([[class.ctor]](class.ctor "11.4.5 Constructors")),
|
||
|
||
- [(1.2)](#1.2)
|
||
|
||
no private or protected direct non-static data members ([[class.access]](class.access "11.8 Member access control")),
|
||
|
||
- [(1.3)](#1.3)
|
||
|
||
no private or protected direct base classes ([[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members")), and
|
||
|
||
- [(1.4)](#1.4)
|
||
|
||
no virtual functions ([[class.virtual]](class.virtual "11.7.3 Virtual functions")) or virtual base classes ([[class.mi]](class.mi "11.7.2 Multiple base classes"))[.](#1.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
Aggregate initialization does not allow accessing
|
||
protected and private base class' members or constructors[.](#1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5492)
|
||
|
||
The [*elements*](#def:aggregate,elements "9.5.2 Aggregates [dcl.init.aggr]") of an aggregate are:
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
for an array, the array elements in increasing subscript order, or
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
for a class, the direct base classes in declaration order,
|
||
followed by the direct non-static data members ([[class.mem]](class.mem "11.4 Class members"))
|
||
that are not members of an anonymous union, in declaration order[.](#2.sentence-1)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5503)
|
||
|
||
When an aggregate is initialized by an initializer list
|
||
as specified in [[dcl.init.list]](dcl.init.list "9.5.5 List-initialization"),
|
||
the elements of the initializer list are taken as initializers
|
||
for the elements of the aggregate[.](#3.sentence-1)
|
||
|
||
The [*explicitly initialized elements*](#def:explicitly_initialized_elements,aggregate "9.5.2 Aggregates [dcl.init.aggr]") of the aggregate are determined as follows:
|
||
|
||
- [(3.1)](#3.1)
|
||
|
||
If the initializer list is
|
||
a brace-enclosed [*designated-initializer-list*](dcl.init.general#nt:designated-initializer-list "9.5.1 General [dcl.init.general]"),
|
||
the aggregate shall be of class type,
|
||
the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") in each [*designator*](dcl.init.general#nt:designator "9.5.1 General [dcl.init.general]") 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[.](#3.1.sentence-1)
|
||
|
||
- [(3.2)](#3.2)
|
||
|
||
If the initializer list is a brace-enclosed [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]"),
|
||
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)[.](#3.2.sentence-1)
|
||
|
||
- [(3.3)](#3.3)
|
||
|
||
Otherwise, the initializer list must be {},
|
||
and there are no explicitly initialized elements[.](#3.3.sentence-1)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5529)
|
||
|
||
For each explicitly initialized element:
|
||
|
||
- [(4.1)](#4.1)
|
||
|
||
If the element is an anonymous union member and
|
||
the initializer list is
|
||
a brace-enclosed [*designated-initializer-list*](dcl.init.general#nt:designated-initializer-list "9.5.1 General [dcl.init.general]"),
|
||
the element is initialized by the[*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") { *D* },
|
||
where *D* is the [*designated-initializer-clause*](dcl.init.general#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]") naming a member of the anonymous union member[.](#4.1.sentence-1)
|
||
There shall be only one such [*designated-initializer-clause*](dcl.init.general#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]")[.](#4.1.sentence-2)
|
||
[*Example [1](#example-1)*:
|
||
struct C {union {int a; const char* p; }; int x;} c = { .a = 1, .x = 3 }; initializes c.a with 1 and c.x with 3[.](#4.1.sentence-3)
|
||
â *end example*]
|
||
|
||
- [(4.2)](#4.2)
|
||
|
||
Otherwise, if the initializer list is
|
||
a brace-enclosed [*designated-initializer-list*](dcl.init.general#nt:designated-initializer-list "9.5.1 General [dcl.init.general]"),
|
||
the element is initialized with the [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") of the corresponding [*designated-initializer-clause*](dcl.init.general#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]")[.](#4.2.sentence-1)
|
||
If that initializer is of the form= [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19 Assignment and compound assignment operators [expr.assign]") and
|
||
a narrowing conversion ([[dcl.init.list]](dcl.init.list "9.5.5 List-initialization")) is required
|
||
to convert the expression, the program is ill-formed[.](#4.2.sentence-2)
|
||
[*Note [2](#note-2)*:
|
||
The form of the initializer determines
|
||
whether copy-initialization or direct-initialization is performed[.](#4.2.sentence-3)
|
||
â *end note*]
|
||
|
||
- [(4.3)](#4.3)
|
||
|
||
Otherwise,
|
||
the initializer list is a brace-enclosed [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]")[.](#4.3.sentence-1)
|
||
If an [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") appertains to the aggregate element,
|
||
then the aggregate element is copy-initialized from the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")[.](#4.3.sentence-2)
|
||
Otherwise,
|
||
the aggregate element is copy-initialized
|
||
from a brace-enclosed [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") consisting of all of the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")*s* that appertain to subobjects of the aggregate element,
|
||
in the order of appearance[.](#4.3.sentence-3)
|
||
[*Note [3](#note-3)*:
|
||
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[.](#4.3.sentence-4)
|
||
â *end note*]
|
||
[*Example [2](#example-2)*:
|
||
struct A {int x; struct B {int i; int j; } b;} a = { 1, { 2, 3 } }; initializesa.x with 1,a.b.i with 2,a.b.j with 3[.](#4.3.sentence-5)
|
||
struct base1 { int b1, b2 = 42; };struct base2 { base2() { b3 = 42; }int b3;};struct derived : base1, base2 {int d;};
|
||
|
||
derived d1{{1, 2}, {}, 4};
|
||
derived d2{{}, {}, 4}; initializesd1.b1 with 1,d1.b2 with 2,d1.b3 with 42,d1.d with 4, andd2.b1 with 0,d2.b2 with 42,d2.b3 with 42,d2.d with 4[.](#4.3.sentence-6)
|
||
â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5628)
|
||
|
||
For a non-union aggregate,
|
||
each element that is not an explicitly initialized element
|
||
is initialized as follows:
|
||
|
||
- [(5.1)](#5.1)
|
||
|
||
If the element has a default member initializer ([[class.mem]](class.mem "11.4 Class members")),
|
||
the element is initialized from that initializer[.](#5.1.sentence-1)
|
||
|
||
- [(5.2)](#5.2)
|
||
|
||
Otherwise, if the element is not a reference, the element
|
||
is copy-initialized from an empty initializer list ([[dcl.init.list]](dcl.init.list "9.5.5 List-initialization"))[.](#5.2.sentence-1)
|
||
|
||
- [(5.3)](#5.3)
|
||
|
||
Otherwise, the program is ill-formed[.](#5.3.sentence-1)
|
||
|
||
If the aggregate is a union and the initializer list is empty, then
|
||
|
||
- [(5.4)](#5.4)
|
||
|
||
if any variant member has a default member initializer,
|
||
that member is initialized from its default member initializer;
|
||
|
||
- [(5.5)](#5.5)
|
||
|
||
otherwise, the first member of the union (if any)
|
||
is copy-initialized from an empty initializer list[.](#5.sentence-2)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5652)
|
||
|
||
[*Example [3](#example-3)*:
|
||
|
||
struct S { int a; const char* b; int c; int d = b[a]; };
|
||
S ss = { 1, "asdf" }; initializesss.a with 1,ss.b with "asdf",ss.c with the value of an expression of the formint{} (that is, 0), and ss.d with the value of ss.b[ss.a] (that is, 's')[.](#6.sentence-1)
|
||
|
||
struct A { string a; int b = 42; int c = -1;};
|
||
|
||
A{.c=21} has the following steps:
|
||
|
||
- [(6.1)](#6.1)
|
||
|
||
Initialize a with {}
|
||
|
||
- [(6.2)](#6.2)
|
||
|
||
Initialize b with = 42
|
||
|
||
- [(6.3)](#6.3)
|
||
|
||
Initialize c with = 21
|
||
|
||
â *end example*]
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5685)
|
||
|
||
The initializations of the elements of the aggregate
|
||
are evaluated in the element order[.](#7.sentence-1)
|
||
|
||
That is,
|
||
all value computations and side effects associated with a given element
|
||
are sequenced before
|
||
those of any element that follows it in order[.](#7.sentence-2)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5693)
|
||
|
||
An aggregate that is a class can also be initialized with a single
|
||
expression not enclosed in braces, as described in [[dcl.init]](dcl.init "9.5 Initializers")[.](#8.sentence-1)
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5697)
|
||
|
||
The destructor for each element of class type
|
||
other than an anonymous union member
|
||
is potentially invoked ([[class.dtor]](class.dtor "11.4.7 Destructors"))
|
||
from the context where the aggregate initialization occurs[.](#9.sentence-1)
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
This provision ensures that destructors can be called
|
||
for fully-constructed subobjects
|
||
in case an exception is thrown ([[except.ctor]](except.ctor "14.3 Stack unwinding"))[.](#9.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5708)
|
||
|
||
The number of elements ([[dcl.array]](dcl.array "9.3.4.5 Arrays")) in an array of unknown bound
|
||
initialized with a brace-enclosed [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") is the number of explicitly initialized elements of the array[.](#10.sentence-1)
|
||
|
||
[*Example [4](#example-4)*:
|
||
|
||
int x[] = { 1, 3, 5 }; declares and initializesx as a one-dimensional array that has three elements
|
||
since no size was specified and there are three initializers[.](#10.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[*Example [5](#example-5)*:
|
||
|
||
Instruct X { int i, j, k; };
|
||
X a[] = { 1, 2, 3, 4, 5, 6 };
|
||
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };a and b have the same value[.](#10.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
An array of unknown bound shall not be initialized with
|
||
an empty [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") {}[.](#10.sentence-4)[79](#footnote-79 "The syntax provides for empty braced-init-lists, but nonetheless C++ does not have zero length arrays.")
|
||
|
||
[*Note [5](#note-5)*:
|
||
|
||
A default member initializer does not determine the bound for a member
|
||
array of unknown bound[.](#10.sentence-5)
|
||
|
||
Since the default member initializer is
|
||
ignored if a suitable [*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]") is present ([[class.base.init]](class.base.init "11.9.3 Initializing bases and members")),
|
||
the default member initializer is not
|
||
considered to initialize the array of unknown bound[.](#10.sentence-6)
|
||
|
||
[*Example [6](#example-6)*: struct S {int y[] = { 0 }; // error: non-static data member of incomplete type}; â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5751)
|
||
|
||
[*Note [6](#note-6)*:
|
||
|
||
Static data members,
|
||
non-static data members of anonymous union members,
|
||
and
|
||
unnamed bit-fields
|
||
are not considered elements of the aggregate[.](#11.sentence-1)
|
||
|
||
[*Example [7](#example-7)*: struct A {int i; static int s; int j; int :17; int k;} a = { 1, 2, 3 };
|
||
|
||
Here, the second initializer 2 initializesa.j and not the static data memberA::s, and the third initializer 3 initializes a.k and not the unnamed bit-field before it[.](#11.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[12](#12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5777)
|
||
|
||
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[.](#12.sentence-1)
|
||
|
||
[*Example [8](#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*]
|
||
|
||
[13](#13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5798)
|
||
|
||
When initializing a multidimensional array,
|
||
the[*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")*s* initialize the elements with the last (rightmost) index of the array
|
||
varying the fastest ([[dcl.array]](dcl.array "9.3.4.5 Arrays"))[.](#13.sentence-1)
|
||
|
||
[*Example [9](#example-9)*:
|
||
|
||
int x[2][2] = { 3, 1, 4, 2 }; initializesx[0][0] to3,x[0][1] to1,x[1][0] to4,
|
||
andx[1][1] to2[.](#13.sentence-2)
|
||
|
||
On the other hand,float y[4][3] = {{ 1 }, { 2 }, { 3 }, { 4 }}; initializes the first column ofy (regarded as a two-dimensional array)
|
||
and leaves the rest zero[.](#13.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
[14](#14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5834)
|
||
|
||
Each [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") in
|
||
a brace-enclosed [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") is said to [*appertain*](dcl.attr.grammar#def:appertain "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") to an element of the aggregate being initialized or
|
||
to an element of one of its subaggregates[.](#14.sentence-1)
|
||
|
||
Considering the sequence of [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")*s*,
|
||
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*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") appertains to
|
||
the corresponding aggregate element if
|
||
|
||
- [(14.1)](#14.1)
|
||
|
||
the aggregate element is not an aggregate, or
|
||
|
||
- [(14.2)](#14.2)
|
||
|
||
the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") begins with a left brace, or
|
||
|
||
- [(14.3)](#14.3)
|
||
|
||
the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") is an expression and
|
||
an implicit conversion sequence can be formed
|
||
that converts the expression to the type of the aggregate element, or
|
||
|
||
- [(14.4)](#14.4)
|
||
|
||
the aggregate element is an aggregate that itself has no aggregate elements[.](#14.sentence-2)
|
||
|
||
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*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")[.](#14.sentence-3)
|
||
|
||
[*Note [7](#note-7)*:
|
||
|
||
These rules apply recursively to the aggregate's subaggregates[.](#14.sentence-4)
|
||
|
||
[*Example [10](#example-10)*:
|
||
|
||
Instruct 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[.](#14.sentence-5)
|
||
|
||
â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
This process continues
|
||
until all [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")*s* have been exhausted[.](#14.sentence-6)
|
||
|
||
If any [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") remains
|
||
that does not appertain to
|
||
an element of the aggregate or one of its subaggregates,
|
||
the program is ill-formed[.](#14.sentence-7)
|
||
|
||
[*Example [11](#example-11)*: char cv[4] = { 'a', 's', 'd', 'f', 0 }; // error: too many initializers â *end example*]
|
||
|
||
[15](#15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5899)
|
||
|
||
[*Example [12](#example-12)*:
|
||
|
||
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 arrayy[0],
|
||
namelyy[0][0],y[0][1],
|
||
andy[0][2][.](#15.sentence-1)
|
||
|
||
Likewise the next two lines initializey[1] andy[2][.](#15.sentence-2)
|
||
|
||
The initializer ends early and thereforey[3]'s
|
||
elements are initialized as if explicitly initialized with an
|
||
expression of the formfloat(),
|
||
that is, are initialized with0.0[.](#15.sentence-3)
|
||
|
||
In the following example, braces in the[*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") are elided;
|
||
however the[*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") has the same effect as the completely-braced[*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") of the above example,float y[4][3] = {1, 3, 5, 2, 4, 6, 3, 5, 7};
|
||
|
||
The initializer fory begins with a left brace, but the one fory[0] does not,
|
||
therefore three elements from the list are used[.](#15.sentence-5)
|
||
|
||
Likewise the next three are taken successively fory[1] andy[2][.](#15.sentence-6)
|
||
|
||
â *end example*]
|
||
|
||
[16](#16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5953)
|
||
|
||
[*Note [8](#note-8)*:
|
||
|
||
The initializer for an empty subaggregate is needed
|
||
if any initializers are provided for subsequent elements[.](#16.sentence-1)
|
||
|
||
[*Example [13](#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*]
|
||
|
||
â *end note*]
|
||
|
||
[17](#17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5977)
|
||
|
||
[*Example [14](#example-14)*: struct A {int i; operator int();};struct B { A a1, a2; int z;};
|
||
A a;
|
||
B b = { 4, a, a };
|
||
|
||
Braces are elided around the[*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") forb.a1.i[.](#17.sentence-1)
|
||
|
||
b.a1.i is initialized with 4,b.a2 is initialized witha,b.z is initialized with whatevera.operator int() returns[.](#17.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[18](#18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6006)
|
||
|
||
[*Note [9](#note-9)*:
|
||
|
||
An aggregate array or an aggregate class can contain elements of a
|
||
class type with a user-declared constructor ([[class.ctor]](class.ctor "11.4.5 Constructors"))[.](#18.sentence-1)
|
||
|
||
Initialization of these aggregate objects is described in [[class.expl.init]](class.expl.init "11.9.2 Explicit initialization")[.](#18.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[19](#19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6014)
|
||
|
||
[*Note [10](#note-10)*:
|
||
|
||
Whether the initialization of aggregates with static storage duration
|
||
is static or dynamic is specified
|
||
in [[basic.start.static]](basic.start.static "6.10.3.2 Static initialization"), [[basic.start.dynamic]](basic.start.dynamic "6.10.3.3 Dynamic initialization of non-block variables"), and [[stmt.dcl]](stmt.dcl "8.10 Declaration statement")[.](#19.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[20](#20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6021)
|
||
|
||
When a union is initialized with an initializer list,
|
||
there shall not be more than one
|
||
explicitly initialized element[.](#20.sentence-1)
|
||
|
||
[*Example [15](#example-15)*: union u { int a; const char* 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*]
|
||
|
||
[21](#21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L6039)
|
||
|
||
[*Note [11](#note-11)*:
|
||
|
||
As described above,
|
||
the braces around the[*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") for a union member can be omitted if the
|
||
union is a member of another aggregate[.](#21.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[79)](#footnote-79)[79)](#footnoteref-79)
|
||
|
||
The syntax provides for empty [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")*s*,
|
||
but nonetheless C++ does not have zero length arrays[.](#footnote-79.sentence-1)
|