From Jason Turner

[dcl.type.auto.deduct]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp_266rw6o/{from.md → to.md} +93 -0
tmp/tmp_266rw6o/{from.md → to.md} RENAMED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##### Placeholder type deduction <a id="dcl.type.auto.deduct">[[dcl.type.auto.deduct]]</a>
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.
16
+ If 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 `decltype(auto)` or cv `auto`.
25
+
26
+ If the deduction is for a `return` statement and `e` is a
27
+ *braced-init-list* ([[dcl.init.list]]), the program is ill-formed.
28
+
29
+ If the placeholder is the `auto` *type-specifier*, the deduced type T'
30
+ replacing `T` is determined using the rules for template argument
31
+ deduction. Obtain `P` from `T` by replacing the occurrences of `auto`
32
+ with either a new invented type template parameter `U` or, if the
33
+ initialization is copy-list-initialization, with
34
+ `std::initializer_list<U>`. Deduce a value for `U` using the rules of
35
+ template argument deduction from a function call (
36
+ [[temp.deduct.call]]), where `P` is a function template parameter type
37
+ and the corresponding argument is `e`. If the deduction fails, the
38
+ declaration is ill-formed. Otherwise, T' is obtained by substituting the
39
+ deduced `U` into `P`.
40
+
41
+ [*Example 9*:
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
47
+ 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 10*:
54
+
55
+ ``` cpp
56
+ const auto &i = expr;
57
+ ```
58
+
59
+ The type of `i` is the deduced type of the parameter `u` in the call
60
+ `f(expr)` of the following invented function template:
61
+
62
+ ``` cpp
63
+ template <class U> void f(const U& u);
64
+ ```
65
+
66
+ — *end example*]
67
+
68
+ If the placeholder is the `decltype(auto)` *type-specifier*, `T` shall
69
+ be the placeholder alone. The type deduced for `T` is determined as
70
+ described in  [[dcl.type.simple]], as though `e` had been the operand of
71
+ the `decltype`.
72
+
73
+ [*Example 11*:
74
+
75
+ ``` cpp
76
+ int i;
77
+ int&& f();
78
+ auto x2a(i); // decltype(x2a) is int
79
+ decltype(auto) x2d(i); // decltype(x2d) is int
80
+ auto x3a = i; // decltype(x3a) is int
81
+ 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, { 1, 2 } is not an expression
88
+ auto *x7a = &i; // decltype(x7a) is int*
89
+ decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)
90
+ ```
91
+
92
+ — *end example*]
93
+