tmp/tmprv729q9_/{from.md → to.md}
RENAMED
|
@@ -2,19 +2,21 @@
|
|
| 2 |
|
| 3 |
When an argument is an initializer list ([[dcl.init.list]]), it is not
|
| 4 |
an expression and special rules apply for converting it to a parameter
|
| 5 |
type.
|
| 6 |
|
| 7 |
-
If the parameter type is `std::initializer_list<X>`
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
conversion can be a user-defined
|
| 12 |
-
call to an initializer-list
|
|
|
|
| 13 |
|
| 14 |
``` cpp
|
| 15 |
void f(std::initializer_list<int>);
|
|
|
|
| 16 |
f( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion
|
| 17 |
f( {'a','b'} ); // OK: f(initializer_list<int>) integral promotion
|
| 18 |
f( {1.0} ); // error: narrowing
|
| 19 |
|
| 20 |
struct A {
|
|
@@ -30,19 +32,27 @@ g({ "foo", "bar" }); // OK, uses #3
|
|
| 30 |
typedef int IA[3];
|
| 31 |
void h(const IA&);
|
| 32 |
h({ 1, 2, 3 }); // OK: identity conversion
|
| 33 |
```
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
Otherwise, if the parameter is a non-aggregate class `X` and overload
|
| 36 |
resolution per [[over.match.list]] chooses a single best constructor of
|
| 37 |
`X` to perform the initialization of an object of type `X` from the
|
| 38 |
argument initializer list, the implicit conversion sequence is a
|
| 39 |
-
user-defined conversion sequence
|
| 40 |
-
|
| 41 |
-
the
|
| 42 |
-
|
| 43 |
-
|
|
|
|
| 44 |
|
| 45 |
``` cpp
|
| 46 |
struct A {
|
| 47 |
A(std::initializer_list<int>);
|
| 48 |
};
|
|
@@ -52,11 +62,11 @@ f( {'a', 'b'} ); // OK: f(A(std::initializer_list<int>)) user-defined
|
|
| 52 |
struct B {
|
| 53 |
B(int, double);
|
| 54 |
};
|
| 55 |
void g(B);
|
| 56 |
g( {'a', 'b'} ); // OK: g(B(int,double)) user-defined conversion
|
| 57 |
-
g( {1.0, 1
|
| 58 |
|
| 59 |
void f(B);
|
| 60 |
f( {'a', 'b'} ); // error: ambiguous f(A) or f(B)
|
| 61 |
|
| 62 |
struct C {
|
|
@@ -64,20 +74,21 @@ struct C {
|
|
| 64 |
};
|
| 65 |
void h(C);
|
| 66 |
h({"foo"}); // OK: h(C(std::string("foo")))
|
| 67 |
|
| 68 |
struct D {
|
| 69 |
-
|
| 70 |
};
|
| 71 |
void i(D);
|
| 72 |
i({ {1,2}, {"bar"} }); // OK: i(D(A(std::initializer_list<int>{1,2\),C(std::string("bar"))))}
|
| 73 |
```
|
| 74 |
|
| 75 |
Otherwise, if the parameter has an aggregate type which can be
|
| 76 |
initialized from the initializer list according to the rules for
|
| 77 |
aggregate initialization ([[dcl.init.aggr]]), the implicit conversion
|
| 78 |
-
sequence is a user-defined conversion sequence
|
|
|
|
| 79 |
|
| 80 |
``` cpp
|
| 81 |
struct A {
|
| 82 |
int m1;
|
| 83 |
double m2;
|
|
|
|
| 2 |
|
| 3 |
When an argument is an initializer list ([[dcl.init.list]]), it is not
|
| 4 |
an expression and special rules apply for converting it to a parameter
|
| 5 |
type.
|
| 6 |
|
| 7 |
+
If the parameter type is `std::initializer_list<X>` and all the elements
|
| 8 |
+
of the initializer list can be implicitly converted to `X`, the implicit
|
| 9 |
+
conversion sequence is the worst conversion necessary to convert an
|
| 10 |
+
element of the list to `X`, or if the initializer list has no elements,
|
| 11 |
+
the identity conversion. This conversion can be a user-defined
|
| 12 |
+
conversion even in the context of a call to an initializer-list
|
| 13 |
+
constructor.
|
| 14 |
|
| 15 |
``` cpp
|
| 16 |
void f(std::initializer_list<int>);
|
| 17 |
+
f( {} ); // OK: f(initializer_list<int>) identity conversion
|
| 18 |
f( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion
|
| 19 |
f( {'a','b'} ); // OK: f(initializer_list<int>) integral promotion
|
| 20 |
f( {1.0} ); // error: narrowing
|
| 21 |
|
| 22 |
struct A {
|
|
|
|
| 32 |
typedef int IA[3];
|
| 33 |
void h(const IA&);
|
| 34 |
h({ 1, 2, 3 }); // OK: identity conversion
|
| 35 |
```
|
| 36 |
|
| 37 |
+
Otherwise, if the parameter type is “array of `N` `X`”[^12], if the
|
| 38 |
+
initializer list has exactly `N` elements or if it has fewer than `N`
|
| 39 |
+
elements and `X` is default-constructible, and if all the elements of
|
| 40 |
+
the initializer list can be implicitly converted to `X`, the implicit
|
| 41 |
+
conversion sequence is the worst conversion necessary to convert an
|
| 42 |
+
element of the list to `X`.
|
| 43 |
+
|
| 44 |
Otherwise, if the parameter is a non-aggregate class `X` and overload
|
| 45 |
resolution per [[over.match.list]] chooses a single best constructor of
|
| 46 |
`X` to perform the initialization of an object of type `X` from the
|
| 47 |
argument initializer list, the implicit conversion sequence is a
|
| 48 |
+
user-defined conversion sequence with the second standard conversion
|
| 49 |
+
sequence an identity conversion. If multiple constructors are viable but
|
| 50 |
+
none is better than the others, the implicit conversion sequence is the
|
| 51 |
+
ambiguous conversion sequence. User-defined conversions are allowed for
|
| 52 |
+
conversion of the initializer list elements to the constructor parameter
|
| 53 |
+
types except as noted in [[over.best.ics]].
|
| 54 |
|
| 55 |
``` cpp
|
| 56 |
struct A {
|
| 57 |
A(std::initializer_list<int>);
|
| 58 |
};
|
|
|
|
| 62 |
struct B {
|
| 63 |
B(int, double);
|
| 64 |
};
|
| 65 |
void g(B);
|
| 66 |
g( {'a', 'b'} ); // OK: g(B(int,double)) user-defined conversion
|
| 67 |
+
g( {1.0, 1.0} ); // error: narrowing
|
| 68 |
|
| 69 |
void f(B);
|
| 70 |
f( {'a', 'b'} ); // error: ambiguous f(A) or f(B)
|
| 71 |
|
| 72 |
struct C {
|
|
|
|
| 74 |
};
|
| 75 |
void h(C);
|
| 76 |
h({"foo"}); // OK: h(C(std::string("foo")))
|
| 77 |
|
| 78 |
struct D {
|
| 79 |
+
D(A, C);
|
| 80 |
};
|
| 81 |
void i(D);
|
| 82 |
i({ {1,2}, {"bar"} }); // OK: i(D(A(std::initializer_list<int>{1,2\),C(std::string("bar"))))}
|
| 83 |
```
|
| 84 |
|
| 85 |
Otherwise, if the parameter has an aggregate type which can be
|
| 86 |
initialized from the initializer list according to the rules for
|
| 87 |
aggregate initialization ([[dcl.init.aggr]]), the implicit conversion
|
| 88 |
+
sequence is a user-defined conversion sequence with the second standard
|
| 89 |
+
conversion sequence an identity conversion.
|
| 90 |
|
| 91 |
``` cpp
|
| 92 |
struct A {
|
| 93 |
int m1;
|
| 94 |
double m2;
|