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 examplestruct 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 examplestruct 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 example
char 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 example
double 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