initializer: brace-or-equal-initializer ( expression-list )
brace-or-equal-initializer: = initializer-clause braced-init-list
initializer-clause: assignment-expression braced-init-list
braced-init-list: { initializer-list , } { designated-initializer-list , } { }
initializer-list: initializer-clause ... initializer-list , initializer-clause ...
designated-initializer-list: designated-initializer-clause designated-initializer-list , designated-initializer-clause
designated-initializer-clause: designator brace-or-equal-initializer
designator: . identifier
expr-or-braced-init-list: expression braced-init-list
X a();
int f(bool b) {
unsigned char c;
unsigned char d = c; // OK, d has an indeterminate value
int e = d; // undefined behavior
return b ? d : 0; // undefined behavior if b is true
} — end example
int a;
struct X {
static int a;
static int b;
};
int X::a = 1;
int X::b = a; // X::b = X::a
— end example
struct A {
int x;
struct B {
int i;
int j;
} b;
} a = { 1, { 2, 3 } };
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};
struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
struct X { int i, j, k = 42; };
X a[] = { 1, 2, 3, 4, 5, 6 };
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
struct A {
string a;
int b = 42;
int c = -1;
};
int x[] = { 1, 3, 5 };
struct S {
int y[] = { 0 }; // error: non-static data member of incomplete type
}; — end example
struct A {
int i;
static int s;
int j;
int :17;
int k;
} a = { 1, 2, 3 };
struct A;
extern A a;
struct A {
const A& a1 { A{a,a} }; // OK
const A& a2 { A{} }; // error
};
A a{a,a}; // OK
— end example
struct S { } s;
struct A {
S s1;
int i1;
S s2;
int i2;
S s3;
int i3;
} a = {
{ }, // Required initialization
0,
s, // Required initialization
0
}; // Initialization not required for A::s3 because A::i3 is also not initialized
— end example
float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};
float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
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 examplechar msg[] = "Syntax error on line %s\n";
int g(int) noexcept;
void f() {
int i;
int& r = i; // r refers to i
r = 1; // the value of i becomes 1
int* p = &r; // p points to i
int& rr = r; // rr refers to what r refers to, that is, to i
int (&rg)(int) = g; // rg refers to the function g
rg(i); // calls function g
int a[3];
int (&ra)[3] = a; // ra refers to the array a
ra[1] = i; // modifies a[1]
} — end exampledouble d = 2.0; double& rd = d; // rd refers to d const double& rcd = d; // rcd refers to d struct A { }; struct B : A { operator int&(); } b; A& ra = b; // ra refers to A subobject in b const A& rca = b; // rca refers to A subobject in b int& ir = B(); // ir refers to the result of B::operator int&— end example
double& rd2 = 2.0; // error: not an lvalue and reference not const int i = 2; double& rd3 = i; // error: type mismatch and reference not const— end example
struct A { };
struct B : A { } b;
extern B f();
const A& rca2 = f(); // bound to the A subobject of the B rvalue.
A&& rra = f(); // same as above
struct X {
operator B();
operator int&();
} x;
const A& r = x; // bound to the A subobject of the result of the conversion
int i2 = 42;
int&& rri = static_cast<int&&>(i2); // bound directly to i2
B&& rrb = x; // bound directly to the result of operator B
— end example
struct Banana { };
struct Enigma { operator const Banana(); };
struct Alaska { operator Banana&(); };
void enigmatic() {
typedef const Banana ConstBanana;
Banana &&banana1 = ConstBanana(); // ill-formed
Banana &&banana2 = Enigma(); // ill-formed
Banana &&banana3 = Alaska(); // ill-formed
}
const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
double&& rrd = 2; // rrd refers to temporary with value 2.0
const volatile int cvi = 1;
const int& r2 = cvi; // error: cv-qualifier dropped
struct A { operator volatile int&(); } a;
const int& r3 = a; // error: cv-qualifier dropped
// from result of conversion function
double d2 = 1.0;
double&& rrd2 = d2; // error: initializer is lvalue of related type
struct X { operator int&(); };
int&& rri2 = X(); // error: result of conversion function is lvalue of related type
int i3 = 2;
double&& rrd3 = i3; // rrd3 refers to temporary with value 2.0
— end example
int a = {1};
std::complex<double> z{1,2};
new std::vector<std::string>{"once", "upon", "a", "time"}; // 4 string elements
f( {"Nicholas","Annemarie"} ); // pass list of two elements
return { "Norah" }; // return list of one element
int* e {}; // initialization to zero / null pointer
x = double{1}; // explicitly construct a double
std::map<std::string,int> anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} }; — end example
struct A { int x; int y; int z; };
A a{.y = 2, .x = 1}; // error: designator order does not match declaration order
A b{.x = 1, .z = 2}; // OK, b.y initialized to 0
— end example
double ad[] = { 1, 2.0 }; // OK
int ai[] = { 1, 2.0 }; // error: narrowing
struct S2 {
int m1;
double m2, m3;
};
S2 s21 = { 1, 2, 3.0 }; // OK
S2 s22 { 1.0, 2, 3 }; // error: narrowing
S2 s23 { }; // OK: default to 0,0,0
— end example
struct S {
S(std::initializer_list<double>); // #1
S(std::initializer_list<int>); // #2
S(); // #3
// ...
};
S s1 = { 1.0, 2.0, 3.0 }; // invoke #1
S s2 = { 1, 2, 3 }; // invoke #2
S s3 = { }; // invoke #3
— end example
struct Map {
Map(std::initializer_list<std::pair<std::string,int>>);
};
Map ship = {{"Sophie",14}, {"Surprise",28}}; — end example
struct S {
// no initializer-list constructors
S(int, double, double); // #1
S(); // #2
// ...
};
S s1 = { 1, 2, 3.0 }; // OK: invoke #1
S s2 { 1.0, 2, 3 }; // error: narrowing
S s3 { }; // OK: invoke #2
— end example
enum byte : unsigned char { };
byte b { 42 }; // OK
byte c = { 42 }; // error
byte d = byte{ 42 }; // OK; same value as b
byte e { -1 }; // error
struct A { byte b; };
A a1 = { { 42 } }; // error
A a2 = { byte{ 42 } }; // OK
void f(byte);
f({ 42 }); // error
enum class Handle : uint32_t { Invalid = 0 };
Handle h { 42 }; // OK
— end example
struct S {
S(std::initializer_list<double>); // #1
S(const std::string&); // #2
// ...
};
const S& r1 = { 1, 2, 3.0 }; // OK: invoke #1
const S& r2 { "Spinach" }; // OK: invoke #2
S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue
const int& i1 = { 1 }; // OK
const int& i2 = { 1.1 }; // error: narrowing
const int (&iar)[2] = { 1, 2 }; // OK: iar is bound to temporary array
— end example
struct A { int i; int j; };
A a1 { 1, 2 }; // aggregate initialization
A a2 { 1.2 }; // error: narrowing
struct B {
B(std::initializer_list<int>);
};
B b1 { 1, 2 }; // creates initializer_list<int> and calls constructor
B b2 { 1, 2.0 }; // error: narrowing
struct C {
C(int i, double j);
};
C c1 = { 1, 2.2 }; // calls constructor with arguments (1, 2.2)
C c2 = { 1.1, 2 }; // error: narrowing
int j { 1 }; // initialize to 1
int k { }; // initialize to 0
— end example
struct X {
X(std::initializer_list<double> v);
};
X x{ 1,2,3 };
const double __a[3] = {double{1}, double{2}, double{3}};
X x(std::initializer_list<double>(__a, __a+3));
typedef std::complex<double> cmplx;
std::vector<cmplx> v1 = { 1, 2, 3 };
void f() {
std::vector<cmplx> v2{ 1, 2, 3 };
std::initializer_list<int> i3 = { 1, 2, 3 };
}
struct A {
std::initializer_list<int> i4;
A() : i4{ 1, 2, 3 } {} // ill-formed, would create a dangling reference
};int x = 999; // x is not a constant expression const int y = 999; const int z = 99; char c1 = x; // OK, though it might narrow (in this case, it does narrow) char c2{x}; // error: might narrow char c3{y}; // error: narrows (assuming char is 8 bits) char c4{z}; // OK: no narrowing needed unsigned char uc1 = {5}; // OK: no narrowing needed unsigned char uc2 = {-1}; // error: narrows unsigned int ui1 = {-1}; // error: narrows signed int si1 = { (unsigned int)-1 }; // error: narrows int ii = {2.0}; // error: narrows float f1 { x }; // error: might narrow float f2 { 7 }; // OK: 7 can be exactly represented as a float int f(int); int a[] = { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level— end example