From Jason Turner

[dcl.init.list]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp2o3rgo0x/{from.md → to.md} +37 -29
tmp/tmp2o3rgo0x/{from.md → to.md} RENAMED
@@ -19,12 +19,12 @@ List-initialization can be used
19
  - as the initializer in a *new-expression* [[expr.new]]
20
  - in a `return` statement [[stmt.return]]
21
  - as a *for-range-initializer* [[stmt.iter]]
22
  - as a function argument [[expr.call]]
23
  - as a subscript [[expr.sub]]
24
- - as an argument to a constructor invocation ([[dcl.init]],
25
- [[expr.type.conv]])
26
  - as an initializer for a non-static data member [[class.mem]]
27
  - in a *mem-initializer* [[class.base.init]]
28
  - on the right-hand side of an assignment [[expr.ass]]
29
 
30
  [*Example 1*:
@@ -56,12 +56,13 @@ initializer list as the argument to the constructor template
56
  `template<class T> C(T)` of a class `C` does not create an
57
  initializer-list constructor, because an initializer list argument
58
  causes the corresponding parameter to be a non-deduced context
59
  [[temp.deduct.call]]. — *end note*]
60
 
61
- The template `std::initializer_list` is not predefined; if the header
62
- `<initializer_list>` is not imported or included prior to a use of
 
63
  `std::initializer_list` — even an implicit use in which the type is not
64
  named [[dcl.spec.auto]] — the program is ill-formed.
65
 
66
  List-initialization of an object or reference of type `T` is defined as
67
  follows:
@@ -100,22 +101,22 @@ follows:
100
  int m1;
101
  double m2, m3;
102
  };
103
  S2 s21 = { 1, 2, 3.0 }; // OK
104
  S2 s22 { 1.0, 2, 3 }; // error: narrowing
105
- S2 s23 { }; // OK: default to 0,0,0
106
  ```
107
 
108
  — *end example*]
109
  - Otherwise, if the initializer list has no elements and `T` is a class
110
  type with a default constructor, the object is value-initialized.
111
  - Otherwise, if `T` is a specialization of `std::initializer_list<E>`,
112
  the object is constructed as described below.
113
  - Otherwise, if `T` is a class type, constructors are considered. The
114
  applicable constructors are enumerated and the best one is chosen
115
- through overload resolution ([[over.match]], [[over.match.list]]). If
116
- a narrowing conversion (see below) is required to convert any of the
117
  arguments, the program is ill-formed.
118
  \[*Example 4*:
119
  ``` cpp
120
  struct S {
121
  S(std::initializer_list<double>); // #1
@@ -144,13 +145,13 @@ follows:
144
  // no initializer-list constructors
145
  S(int, double, double); // #1
146
  S(); // #2
147
  // ...
148
  };
149
- S s1 = { 1, 2, 3.0 }; // OK: invoke #1
150
  S s2 { 1.0, 2, 3 }; // error: narrowing
151
- S s3 { }; // OK: invoke #2
152
  ```
153
 
154
  — *end example*]
155
  - Otherwise, if `T` is an enumeration with a fixed underlying type
156
  [[dcl.enum]] `U`, the *initializer-list* has a single element `v`, `v`
@@ -191,32 +192,32 @@ follows:
191
  int x2 {2.0}; // error: narrowing
192
  ```
193
 
194
  — *end example*]
195
  - Otherwise, if `T` is a reference type, a prvalue is generated. The
196
- prvalue initializes its result object by copy-list-initialization. The
197
- prvalue is then used to direct-initialize the reference. The type of
198
- the temporary is the type referenced by `T`, unless `T` is “reference
199
- to array of unknown bound of `U`”, in which case the type of the
200
- temporary is the type of `x` in the declaration `U x[] H`, where H is
201
- the initializer list.
202
  \[*Note 3*: As usual, the binding will fail and the program is
203
  ill-formed if the reference type is an lvalue reference to a non-const
204
  type. — *end note*]
205
  \[*Example 9*:
206
  ``` cpp
207
  struct S {
208
  S(std::initializer_list<double>); // #1
209
  S(const std::string&); // #2
210
  // ...
211
  };
212
- const S& r1 = { 1, 2, 3.0 }; // OK: invoke #1
213
- const S& r2 { "Spinach" }; // OK: invoke #2
214
  S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue
215
  const int& i1 = { 1 }; // OK
216
  const int& i2 = { 1.1 }; // error: narrowing
217
- const int (&iar)[2] = { 1, 2 }; // OK: iar is bound to temporary array
218
 
219
  struct A { } a;
220
  struct B { explicit B(const A&); };
221
  const B& b2{a}; // error: cannot copy-list-initialize B temporary from A
222
  ```
@@ -335,27 +336,34 @@ variable, so the array persists for the lifetime of the variable. For
335
  member, so the program is ill-formed [[class.base.init]].
336
 
337
  — *end example*]
338
 
339
  [*Note 6*: The implementation is free to allocate the array in
340
- read-only memory if an explicit array with the same initializer could be
341
  so allocated. — *end note*]
342
 
343
  A *narrowing conversion* is an implicit conversion
344
 
345
  - from a floating-point type to an integer type, or
346
- - from `long double` to `double` or `float`, or from `double` to
347
- `float`, except where the source is a constant expression and the
 
348
  actual value after conversion is within the range of values that can
349
  be represented (even if it cannot be represented exactly), or
350
  - from an integer type or unscoped enumeration type to a floating-point
351
  type, except where the source is a constant expression and the actual
352
  value after conversion will fit into the target type and will produce
353
  the original value when converted back to the original type, or
354
  - from an integer type or unscoped enumeration type to an integer type
355
  that cannot represent all the values of the original type, except
356
- where the source is a constant expression whose value after integral
 
 
 
 
 
 
357
  promotions will fit into the target type, or
358
  - from a pointer type or a pointer-to-member type to `bool`.
359
 
360
  [*Note 7*: As indicated above, such conversions are not allowed at the
361
  top level in list-initializations. — *end note*]
@@ -364,24 +372,24 @@ top level in list-initializations. — *end note*]
364
 
365
  ``` cpp
366
  int x = 999; // x is not a constant expression
367
  const int y = 999;
368
  const int z = 99;
369
- char c1 = x; // OK, though it might narrow (in this case, it does narrow)
370
- char c2{x}; // error: might narrow
371
  char c3{y}; // error: narrows (assuming char is 8 bits)
372
- char c4{z}; // OK: no narrowing needed
373
- unsigned char uc1 = {5}; // OK: no narrowing needed
374
  unsigned char uc2 = {-1}; // error: narrows
375
  unsigned int ui1 = {-1}; // error: narrows
376
  signed int si1 =
377
  { (unsigned int)-1 }; // error: narrows
378
  int ii = {2.0}; // error: narrows
379
- float f1 { x }; // error: might narrow
380
- float f2 { 7 }; // OK: 7 can be exactly represented as a float
381
  bool b = {"meow"}; // error: narrows
382
  int f(int);
383
- int a[] = { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level
384
  ```
385
 
386
  — *end example*]
387
 
 
19
  - as the initializer in a *new-expression* [[expr.new]]
20
  - in a `return` statement [[stmt.return]]
21
  - as a *for-range-initializer* [[stmt.iter]]
22
  - as a function argument [[expr.call]]
23
  - as a subscript [[expr.sub]]
24
+ - as an argument to a constructor invocation
25
+ [[dcl.init]], [[expr.type.conv]]
26
  - as an initializer for a non-static data member [[class.mem]]
27
  - in a *mem-initializer* [[class.base.init]]
28
  - on the right-hand side of an assignment [[expr.ass]]
29
 
30
  [*Example 1*:
 
56
  `template<class T> C(T)` of a class `C` does not create an
57
  initializer-list constructor, because an initializer list argument
58
  causes the corresponding parameter to be a non-deduced context
59
  [[temp.deduct.call]]. — *end note*]
60
 
61
+ The template `std::initializer_list` is not predefined; if a standard
62
+ library declaration [[initializer.list.syn]], [[std.modules]] of
63
+ `std::initializer_list` is not reachable from [[module.reach]] a use of
64
  `std::initializer_list` — even an implicit use in which the type is not
65
  named [[dcl.spec.auto]] — the program is ill-formed.
66
 
67
  List-initialization of an object or reference of type `T` is defined as
68
  follows:
 
101
  int m1;
102
  double m2, m3;
103
  };
104
  S2 s21 = { 1, 2, 3.0 }; // OK
105
  S2 s22 { 1.0, 2, 3 }; // error: narrowing
106
+ S2 s23 { }; // OK, default to 0,0,0
107
  ```
108
 
109
  — *end example*]
110
  - Otherwise, if the initializer list has no elements and `T` is a class
111
  type with a default constructor, the object is value-initialized.
112
  - Otherwise, if `T` is a specialization of `std::initializer_list<E>`,
113
  the object is constructed as described below.
114
  - Otherwise, if `T` is a class type, constructors are considered. The
115
  applicable constructors are enumerated and the best one is chosen
116
+ through overload resolution [[over.match]], [[over.match.list]]. If a
117
+ narrowing conversion (see below) is required to convert any of the
118
  arguments, the program is ill-formed.
119
  \[*Example 4*:
120
  ``` cpp
121
  struct S {
122
  S(std::initializer_list<double>); // #1
 
145
  // no initializer-list constructors
146
  S(int, double, double); // #1
147
  S(); // #2
148
  // ...
149
  };
150
+ S s1 = { 1, 2, 3.0 }; // OK, invoke #1
151
  S s2 { 1.0, 2, 3 }; // error: narrowing
152
+ S s3 { }; // OK, invoke #2
153
  ```
154
 
155
  — *end example*]
156
  - Otherwise, if `T` is an enumeration with a fixed underlying type
157
  [[dcl.enum]] `U`, the *initializer-list* has a single element `v`, `v`
 
192
  int x2 {2.0}; // error: narrowing
193
  ```
194
 
195
  — *end example*]
196
  - Otherwise, if `T` is a reference type, a prvalue is generated. The
197
+ prvalue initializes its result object by copy-list-initialization from
198
+ the initializer list. The prvalue is then used to direct-initialize
199
+ the reference. The type of the prvalue is the type referenced by `T`,
200
+ unless `T` is “reference to array of unknown bound of `U`”, in which
201
+ case the type of the prvalue is the type of `x` in the declaration
202
+ `U x[] H`, where H is the initializer list.
203
  \[*Note 3*: As usual, the binding will fail and the program is
204
  ill-formed if the reference type is an lvalue reference to a non-const
205
  type. — *end note*]
206
  \[*Example 9*:
207
  ``` cpp
208
  struct S {
209
  S(std::initializer_list<double>); // #1
210
  S(const std::string&); // #2
211
  // ...
212
  };
213
+ const S& r1 = { 1, 2, 3.0 }; // OK, invoke #1
214
+ const S& r2 { "Spinach" }; // OK, invoke #2
215
  S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue
216
  const int& i1 = { 1 }; // OK
217
  const int& i2 = { 1.1 }; // error: narrowing
218
+ const int (&iar)[2] = { 1, 2 }; // OK, iar is bound to temporary array
219
 
220
  struct A { } a;
221
  struct B { explicit B(const A&); };
222
  const B& b2{a}; // error: cannot copy-list-initialize B temporary from A
223
  ```
 
336
  member, so the program is ill-formed [[class.base.init]].
337
 
338
  — *end example*]
339
 
340
  [*Note 6*: The implementation is free to allocate the array in
341
+ read-only memory if an explicit array with the same initializer can be
342
  so allocated. — *end note*]
343
 
344
  A *narrowing conversion* is an implicit conversion
345
 
346
  - from a floating-point type to an integer type, or
347
+ - from a floating-point type `T` to another floating-point type whose
348
+ floating-point conversion rank is neither greater than nor equal to
349
+ that of `T`, except where the source is a constant expression and the
350
  actual value after conversion is within the range of values that can
351
  be represented (even if it cannot be represented exactly), or
352
  - from an integer type or unscoped enumeration type to a floating-point
353
  type, except where the source is a constant expression and the actual
354
  value after conversion will fit into the target type and will produce
355
  the original value when converted back to the original type, or
356
  - from an integer type or unscoped enumeration type to an integer type
357
  that cannot represent all the values of the original type, except
358
+ where
359
+ - the source is a bit-field whose width w is less than that of its
360
+ type (or, for an enumeration type, its underlying type) and the
361
+ target type can represent all the values of a hypothetical extended
362
+ integer type with width w and with the same signedness as the
363
+ original type or
364
+ - the source is a constant expression whose value after integral
365
  promotions will fit into the target type, or
366
  - from a pointer type or a pointer-to-member type to `bool`.
367
 
368
  [*Note 7*: As indicated above, such conversions are not allowed at the
369
  top level in list-initializations. — *end note*]
 
372
 
373
  ``` cpp
374
  int x = 999; // x is not a constant expression
375
  const int y = 999;
376
  const int z = 99;
377
+ char c1 = x; // OK, though it potentially narrows (in this case, it does narrow)
378
+ char c2{x}; // error: potentially narrows
379
  char c3{y}; // error: narrows (assuming char is 8 bits)
380
+ char c4{z}; // OK, no narrowing needed
381
+ unsigned char uc1 = {5}; // OK, no narrowing needed
382
  unsigned char uc2 = {-1}; // error: narrows
383
  unsigned int ui1 = {-1}; // error: narrows
384
  signed int si1 =
385
  { (unsigned int)-1 }; // error: narrows
386
  int ii = {2.0}; // error: narrows
387
+ float f1 { x }; // error: potentially narrows
388
+ float f2 { 7 }; // OK, 7 can be exactly represented as a float
389
  bool b = {"meow"}; // error: narrows
390
  int f(int);
391
+ int a[] = { 2, f(2), f(2.0) }; // OK, the double-to-int conversion is not at the top level
392
  ```
393
 
394
  — *end example*]
395