tmp/tmplneuj2rs/{from.md → to.md}
RENAMED
|
@@ -2,45 +2,46 @@
|
|
| 2 |
|
| 3 |
*Placeholder type deduction* is the process by which a type containing a
|
| 4 |
placeholder type is replaced by a deduced type.
|
| 5 |
|
| 6 |
A type `T` containing a placeholder type, and a corresponding
|
| 7 |
-
initializer
|
| 8 |
|
| 9 |
- for a non-discarded `return` statement that occurs in a function
|
| 10 |
declared with a return type that contains a placeholder type, `T` is
|
| 11 |
-
the declared return type and
|
| 12 |
-
statement. If the `return` statement has no operand, then
|
| 13 |
`void()`;
|
| 14 |
- for a variable declared with a type that contains a placeholder type,
|
| 15 |
-
`T` is the declared type of the variable and
|
| 16 |
-
|
| 17 |
shall be a *braced-init-list* containing only a single
|
| 18 |
-
*assignment-expression* and
|
| 19 |
- for a non-type template parameter declared with a type that contains a
|
| 20 |
placeholder type, `T` is the declared type of the non-type template
|
| 21 |
-
parameter and
|
| 22 |
|
| 23 |
In the case of a `return` statement with no operand or with an operand
|
| 24 |
-
of type `void`, `T` shall be either
|
|
|
|
| 25 |
|
| 26 |
-
If the deduction is for a `return` statement and
|
| 27 |
-
*braced-init-list*
|
| 28 |
|
| 29 |
-
If the placeholder is the
|
| 30 |
-
replacing `T` is determined using the rules
|
| 31 |
-
deduction. Obtain `P` from `T` by replacing the
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
`std::initializer_list<U>`. Deduce a
|
| 35 |
-
template argument deduction from a
|
| 36 |
-
[[temp.deduct.call]]
|
| 37 |
-
and the corresponding argument is
|
| 38 |
-
declaration is ill-formed. Otherwise, T' is obtained by
|
| 39 |
-
deduced `U` into `P`.
|
| 40 |
|
| 41 |
-
[*Example
|
| 42 |
|
| 43 |
``` cpp
|
| 44 |
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
|
| 45 |
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
|
| 46 |
auto x3{ 1, 2 }; // error: not a single element
|
|
@@ -48,11 +49,11 @@ auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
|
|
| 48 |
auto x5{ 3 }; // decltype(x5) is int
|
| 49 |
```
|
| 50 |
|
| 51 |
— *end example*]
|
| 52 |
|
| 53 |
-
[*Example
|
| 54 |
|
| 55 |
``` cpp
|
| 56 |
const auto &i = expr;
|
| 57 |
```
|
| 58 |
|
|
@@ -63,16 +64,16 @@ The type of `i` is the deduced type of the parameter `u` in the call
|
|
| 63 |
template <class U> void f(const U& u);
|
| 64 |
```
|
| 65 |
|
| 66 |
— *end example*]
|
| 67 |
|
| 68 |
-
If the placeholder is the
|
| 69 |
-
be the placeholder alone. The type deduced
|
| 70 |
-
described in [[dcl.type.simple]], as though
|
| 71 |
-
the `decltype`.
|
| 72 |
|
| 73 |
-
[*Example
|
| 74 |
|
| 75 |
``` cpp
|
| 76 |
int i;
|
| 77 |
int&& f();
|
| 78 |
auto x2a(i); // decltype(x2a) is int
|
|
@@ -82,12 +83,16 @@ decltype(auto) x3d = i; // decltype(x3d) is int
|
|
| 82 |
auto x4a = (i); // decltype(x4a) is int
|
| 83 |
decltype(auto) x4d = (i); // decltype(x4d) is int&
|
| 84 |
auto x5a = f(); // decltype(x5a) is int
|
| 85 |
decltype(auto) x5d = f(); // decltype(x5d) is int&&
|
| 86 |
auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
|
| 87 |
-
decltype(auto) x6d = { 1, 2 }; // error
|
| 88 |
auto *x7a = &i; // decltype(x7a) is int*
|
| 89 |
-
decltype(auto)*x7d = &i; // error
|
| 90 |
```
|
| 91 |
|
| 92 |
— *end example*]
|
| 93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
*Placeholder type deduction* is the process by which a type containing a
|
| 4 |
placeholder type is replaced by a deduced type.
|
| 5 |
|
| 6 |
A type `T` containing a placeholder type, and a corresponding
|
| 7 |
+
initializer E, are determined as follows:
|
| 8 |
|
| 9 |
- for a non-discarded `return` statement that occurs in a function
|
| 10 |
declared with a return type that contains a placeholder type, `T` is
|
| 11 |
+
the declared return type and E is the operand of the `return`
|
| 12 |
+
statement. If the `return` statement has no operand, then E is
|
| 13 |
`void()`;
|
| 14 |
- for a variable declared with a type that contains a placeholder type,
|
| 15 |
+
`T` is the declared type of the variable and E is the initializer. If
|
| 16 |
+
the initialization is direct-list-initialization, the initializer
|
| 17 |
shall be a *braced-init-list* containing only a single
|
| 18 |
+
*assignment-expression* and E is the *assignment-expression*;
|
| 19 |
- for a non-type template parameter declared with a type that contains a
|
| 20 |
placeholder type, `T` is the declared type of the non-type template
|
| 21 |
+
parameter and E is the corresponding template argument.
|
| 22 |
|
| 23 |
In the case of a `return` statement with no operand or with an operand
|
| 24 |
+
of type `void`, `T` shall be either *type-constraint*ₒₚₜ
|
| 25 |
+
`decltype(auto)` or cv *type-constraint*ₒₚₜ `auto`.
|
| 26 |
|
| 27 |
+
If the deduction is for a `return` statement and E is a
|
| 28 |
+
*braced-init-list* [[dcl.init.list]], the program is ill-formed.
|
| 29 |
|
| 30 |
+
If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
|
| 31 |
+
`auto`, the deduced type T' replacing `T` is determined using the rules
|
| 32 |
+
for template argument deduction. Obtain `P` from `T` by replacing the
|
| 33 |
+
occurrences of *type-constraint*ₒₚₜ `auto` either with a new invented
|
| 34 |
+
type template parameter `U` or, if the initialization is
|
| 35 |
+
copy-list-initialization, with `std::initializer_list<U>`. Deduce a
|
| 36 |
+
value for `U` using the rules of template argument deduction from a
|
| 37 |
+
function call [[temp.deduct.call]], where `P` is a function template
|
| 38 |
+
parameter type and the corresponding argument is E. If the deduction
|
| 39 |
+
fails, the declaration is ill-formed. Otherwise, T' is obtained by
|
| 40 |
+
substituting the deduced `U` into `P`.
|
| 41 |
|
| 42 |
+
[*Example 8*:
|
| 43 |
|
| 44 |
``` cpp
|
| 45 |
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
|
| 46 |
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
|
| 47 |
auto x3{ 1, 2 }; // error: not a single element
|
|
|
|
| 49 |
auto x5{ 3 }; // decltype(x5) is int
|
| 50 |
```
|
| 51 |
|
| 52 |
— *end example*]
|
| 53 |
|
| 54 |
+
[*Example 9*:
|
| 55 |
|
| 56 |
``` cpp
|
| 57 |
const auto &i = expr;
|
| 58 |
```
|
| 59 |
|
|
|
|
| 64 |
template <class U> void f(const U& u);
|
| 65 |
```
|
| 66 |
|
| 67 |
— *end example*]
|
| 68 |
|
| 69 |
+
If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
|
| 70 |
+
`decltype(auto)`, `T` shall be the placeholder alone. The type deduced
|
| 71 |
+
for `T` is determined as described in [[dcl.type.simple]], as though E
|
| 72 |
+
had been the operand of the `decltype`.
|
| 73 |
|
| 74 |
+
[*Example 10*:
|
| 75 |
|
| 76 |
``` cpp
|
| 77 |
int i;
|
| 78 |
int&& f();
|
| 79 |
auto x2a(i); // decltype(x2a) is int
|
|
|
|
| 83 |
auto x4a = (i); // decltype(x4a) is int
|
| 84 |
decltype(auto) x4d = (i); // decltype(x4d) is int&
|
| 85 |
auto x5a = f(); // decltype(x5a) is int
|
| 86 |
decltype(auto) x5d = f(); // decltype(x5d) is int&&
|
| 87 |
auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
|
| 88 |
+
decltype(auto) x6d = { 1, 2 }; // error: { 1, 2 } is not an expression
|
| 89 |
auto *x7a = &i; // decltype(x7a) is int*
|
| 90 |
+
decltype(auto)*x7d = &i; // error: declared type is not plain decltype(auto)
|
| 91 |
```
|
| 92 |
|
| 93 |
— *end example*]
|
| 94 |
|
| 95 |
+
For a *placeholder-type-specifier* with a *type-constraint*, the
|
| 96 |
+
immediately-declared constraint [[temp.param]] of the *type-constraint*
|
| 97 |
+
for the type deduced for the placeholder shall be satisfied.
|
| 98 |
+
|