From Jason Turner

[dcl.type.auto.deduct]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpi5fxs06g/{from.md → to.md} +49 -28
tmp/tmpi5fxs06g/{from.md → to.md} RENAMED
@@ -2,44 +2,63 @@
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>
@@ -66,12 +85,12 @@ template <class U> void f(const U& u);
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;
@@ -86,10 +105,12 @@ 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
 
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-clause* 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.
12
+ - If the `return` statement has no operand, then E is `void()`.
13
+ - If the operand is a *braced-init-list* [[dcl.init.list]], the
14
+ program is ill-formed.
15
+ - If the operand is an *expression* X that is not an
16
+ *assignment-expression*, E is `(X)`. \[*Note 4*: A comma expression
17
+ [[expr.comma]] is not an *assignment-expression*. *end note*]
18
+ - Otherwise, E is the operand of the `return` statement.
19
+
20
+ If E has type `void`, `T` shall be either *type-constraint*ₒₚₜ
21
+ `decltype(auto)` or cv *type-constraint*ₒₚₜ `auto`.
22
+ - For a variable declared with a type that contains a placeholder type,
23
+ `T` is the declared type of the variable.
24
+ - If the initializer of the variable is a *brace-or-equal-initializer*
25
+ of the form `= initializer-clause`, E is the *initializer-clause*.
26
+ - If the initializer is a *braced-init-list*, it shall consist of a
27
+ single brace-enclosed *assignment-expression* and E is the
28
+ *assignment-expression*.
29
+ - If the initializer is a parenthesized *expression-list*, the
30
+ *expression-list* shall be a single *assignment-expression* and E is
31
+ the *assignment-expression*.
32
+ - For an explicit type conversion [[expr.type.conv]], `T` is the
33
+ specified type, which shall be `auto`.
34
+ - If the initializer is a *braced-init-list*, it shall consist of a
35
+ single brace-enclosed *assignment-expression* and E is the
36
+ *assignment-expression*.
37
+ - If the initializer is a parenthesized *expression-list*, the
38
+ *expression-list* shall be a single *assignment-expression* and E is
39
+ the *assignment-expression*.
40
+ - For a non-type template parameter declared with a type that contains a
41
  placeholder type, `T` is the declared type of the non-type template
42
  parameter and E is the corresponding template argument.
43
 
44
+ `T` shall not be an array type.
 
 
 
 
 
45
 
46
  If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
47
  `auto`, the deduced type T' replacing `T` is determined using the rules
48
+ for template argument deduction. If the initialization is
49
+ copy-list-initialization, a declaration of `std::initializer_list` shall
50
+ precede [[basic.lookup.general]] the *placeholder-type-specifier*.
51
+ Obtain `P` from `T` by replacing the occurrences of
52
+ *type-constraint*ₒₚₜ `auto` either with a new invented type template
53
+ parameter `U` or, if the initialization is copy-list-initialization,
54
+ with `std::initializer_list<U>`. Deduce a value for `U` using the rules
55
+ of template argument deduction from a function call
56
+ [[temp.deduct.call]], where `P` is a function template parameter type
57
+ and the corresponding argument is E. If the deduction fails, the
58
+ declaration is ill-formed. Otherwise, T' is obtained by substituting the
59
+ deduced `U` into `P`.
60
 
61
  [*Example 8*:
62
 
63
  ``` cpp
64
  auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
 
85
 
86
  — *end example*]
87
 
88
  If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
89
  `decltype(auto)`, `T` shall be the placeholder alone. The type deduced
90
+ for `T` is determined as described in  [[dcl.type.decltype]], as though
91
+ E had been the operand of the `decltype`.
92
 
93
  [*Example 10*:
94
 
95
  ``` cpp
96
  int i;
 
105
  decltype(auto) x5d = f(); // decltype(x5d) is int&&
106
  auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
107
  decltype(auto) x6d = { 1, 2 }; // error: { 1, 2 } is not an expression
108
  auto *x7a = &i; // decltype(x7a) is int*
109
  decltype(auto)*x7d = &i; // error: declared type is not plain decltype(auto)
110
+ auto f1(int x) -> decltype((x)) { return (x); } // return type is int&
111
+ auto f2(int x) -> decltype(auto) { return (x); } // return type is int&&
112
  ```
113
 
114
  — *end example*]
115
 
116
  For a *placeholder-type-specifier* with a *type-constraint*, the