From Jason Turner

[dcl.spec.auto]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmperroet7g/{from.md → to.md} +69 -43
tmp/tmperroet7g/{from.md → to.md} RENAMED
@@ -7,64 +7,76 @@ placeholder-type-specifier:
7
  type-constraintₒₚₜ auto
8
  type-constraintₒₚₜ decltype '(' auto ')'
9
  ```
10
 
11
  A *placeholder-type-specifier* designates a placeholder type that will
12
- be replaced later by deduction from an initializer.
13
 
14
- A *placeholder-type-specifier* of the form *type-constraint*ₒₚₜ `auto`
15
- can be used as a *decl-specifier* of the *decl-specifier-seq* of a
16
- *parameter-declaration* of a function declaration or *lambda-expression*
17
- and, if it is not the `auto` *type-specifier* introducing a
18
- *trailing-return-type* (see below), is a *generic parameter type
19
- placeholder* of the function declaration or *lambda-expression*.
 
 
 
 
 
 
 
20
 
21
  [*Note 1*: Having a generic parameter type placeholder signifies that
22
  the function is an abbreviated function template [[dcl.fct]] or the
23
  lambda is a generic lambda [[expr.prim.lambda]]. — *end note*]
24
 
25
- A placeholder type can appear with a function declarator in the
26
- *decl-specifier-seq*, *type-specifier-seq*, *conversion-function-id*, or
27
- *trailing-return-type*, in any context where such a declarator is valid.
28
- If the function declarator includes a *trailing-return-type*
29
- [[dcl.fct]], that *trailing-return-type* specifies the declared return
30
- type of the function. Otherwise, the function declarator shall declare a
31
- function. If the declared return type of the function contains a
32
- placeholder type, the return type of the function is deduced from
33
- non-discarded `return` statements, if any, in the body of the function
34
- [[stmt.if]].
35
 
36
  The type of a variable declared using a placeholder type is deduced from
37
  its initializer. This use is allowed in an initializing declaration
38
  [[dcl.init]] of a variable. The placeholder type shall appear as one of
39
- the *decl-specifier*s in the *decl-specifier-seq* and the
40
- *decl-specifier-seq* shall be followed by one or more *declarator*s,
41
- each of which shall be followed by a non-empty *initializer*.
 
 
42
 
43
  [*Example 1*:
44
 
45
  ``` cpp
46
  auto x = 5; // OK, x has type int
47
  const auto *v = &x, u = 6; // OK, v has type const int*, u has type const int
48
  static auto y = 0.0; // OK, y has type double
49
  auto int r; // error: auto is not a storage-class-specifier
50
  auto f() -> int; // OK, f returns int
51
  auto g() { return 0.0; } // OK, g returns double
 
52
  auto h(); // OK, h's return type will be deduced when it is defined
53
  ```
54
 
55
  — *end example*]
56
 
57
  The `auto` *type-specifier* can also be used to introduce a structured
58
  binding declaration [[dcl.struct.bind]].
59
 
60
- A placeholder type can also be used in the *type-specifier-seq* in the
61
- *new-type-id* or *type-id* of a *new-expression* [[expr.new]] and as a
62
- *decl-specifier* of the *parameter-declaration*'s *decl-specifier-seq*
63
- in a *template-parameter* [[temp.param]]. The `auto` *type-specifier*
64
- can also be used as the *simple-type-specifier* in an explicit type
65
- conversion (functional notation) [[expr.type.conv]].
 
 
 
 
66
 
67
  A program that uses a placeholder type in a context not explicitly
68
  allowed in [[dcl.spec.auto]] is ill-formed.
69
 
70
  If the *init-declarator-list* contains more than one *init-declarator*,
@@ -128,10 +140,25 @@ auto sum(int i) {
128
  }
129
  ```
130
 
131
  — *end example*]
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  Return type deduction for a templated function with a placeholder in its
134
  declared type occurs when the definition is instantiated even if the
135
  function body contains a `return` statement with a non-type-dependent
136
  operand.
137
 
@@ -139,11 +166,11 @@ operand.
139
  template will cause an implicit instantiation. Any errors that arise
140
  from this instantiation are not in the immediate context of the function
141
  type and can result in the program being ill-formed
142
  [[temp.deduct]]. — *end note*]
143
 
144
- [*Example 5*:
145
 
146
  ``` cpp
147
  template <class T> auto f(T t) { return t; } // return type deduced at instantiation time
148
  typedef decltype(f(1)) fint_t; // instantiates f<int> to deduce return type
149
  template<class T> auto f(T* t) { return *t; }
@@ -156,11 +183,11 @@ void g() { int (*p)(int*) = &f; } // instantiates both fs to deter
156
  If a function or function template F has a declared return type that
157
  uses a placeholder type, redeclarations or specializations of F shall
158
  use that placeholder type, not a deduced type; otherwise, they shall not
159
  use a placeholder type.
160
 
161
- [*Example 6*:
162
 
163
  ``` cpp
164
  auto f();
165
  auto f() { return 42; } // return type is int
166
  auto f(); // OK
@@ -201,11 +228,11 @@ shall not be a coroutine [[dcl.fct.def.coroutine]].
201
  An explicit instantiation declaration [[temp.explicit]] does not cause
202
  the instantiation of an entity declared using a placeholder type, but it
203
  also does not prevent that entity from being instantiated as needed to
204
  determine its type.
205
 
206
- [*Example 7*:
207
 
208
  ``` cpp
209
  template <typename T> auto f(T t) { return t; }
210
  extern template auto f(int); // does not instantiate f<int>
211
  int (*p)(int) = f; // instantiates f<int> to determine its return type, but an explicit
@@ -251,32 +278,31 @@ A type `T` containing a placeholder type, and a corresponding
251
  single brace-enclosed *assignment-expression* and E is the
252
  *assignment-expression*.
253
  - If the initializer is a parenthesized *expression-list*, the
254
  *expression-list* shall be a single *assignment-expression* and E is
255
  the *assignment-expression*.
256
- - For a non-type template parameter declared with a type that contains a
257
- placeholder type, `T` is the declared type of the non-type template
258
  parameter and E is the corresponding template argument.
259
 
260
  `T` shall not be an array type.
261
 
262
  If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
263
  `auto`, the deduced type T' replacing `T` is determined using the rules
264
  for template argument deduction. If the initialization is
265
  copy-list-initialization, a declaration of `std::initializer_list` shall
266
  precede [[basic.lookup.general]] the *placeholder-type-specifier*.
267
- Obtain `P` from `T` by replacing the occurrences of
268
- *type-constraint*ₒₚₜ `auto` either with a new invented type template
269
- parameter `U` or, if the initialization is copy-list-initialization,
270
- with `std::initializer_list<U>`. Deduce a value for `U` using the rules
271
- of template argument deduction from a function call
272
- [[temp.deduct.call]], where `P` is a function template parameter type
273
- and the corresponding argument is E. If the deduction fails, the
274
- declaration is ill-formed. Otherwise, T' is obtained by substituting the
275
- deduced `U` into `P`.
276
 
277
- [*Example 8*:
278
 
279
  ``` cpp
280
  auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
281
  auto x2 = { 1, 2.0 }; // error: cannot deduce element type
282
  auto x3{ 1, 2 }; // error: not a single element
@@ -284,11 +310,11 @@ auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
284
  auto x5{ 3 }; // decltype(x5) is int
285
  ```
286
 
287
  — *end example*]
288
 
289
- [*Example 9*:
290
 
291
  ``` cpp
292
  const auto &i = expr;
293
  ```
294
 
@@ -304,11 +330,11 @@ template <class U> void f(const U& u);
304
  If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
305
  `decltype(auto)`, `T` shall be the placeholder alone. The type deduced
306
  for `T` is determined as described in  [[dcl.type.decltype]], as though
307
  E had been the operand of the `decltype`.
308
 
309
- [*Example 10*:
310
 
311
  ``` cpp
312
  int i;
313
  int&& f();
314
  auto x2a(i); // decltype(x2a) is int
 
7
  type-constraintₒₚₜ auto
8
  type-constraintₒₚₜ decltype '(' auto ')'
9
  ```
10
 
11
  A *placeholder-type-specifier* designates a placeholder type that will
12
+ be replaced later, typically by deduction from an initializer.
13
 
14
+ The type of a *parameter-declaration* of a
15
+
16
+ - function declaration [[dcl.fct]],
17
+ - *lambda-expression* [[expr.prim.lambda]], or
18
+ - *template-parameter* [[temp.param]]
19
+
20
+ can be declared using a *placeholder-type-specifier* of the form
21
+ *type-constraint*ₒₚₜ `auto`. The placeholder type shall appear as one
22
+ of the *decl-specifier*s in the *decl-specifier-seq* or as one of the
23
+ *type-specifier*s in a *trailing-return-type* that specifies the type
24
+ that replaces such a *decl-specifier* (see below); the placeholder type
25
+ is a *generic parameter type placeholder* of the function declaration,
26
+ *lambda-expression*, or *template-parameter*, respectively.
27
 
28
  [*Note 1*: Having a generic parameter type placeholder signifies that
29
  the function is an abbreviated function template [[dcl.fct]] or the
30
  lambda is a generic lambda [[expr.prim.lambda]]. — *end note*]
31
 
32
+ A placeholder type can appear in the *decl-specifier-seq* for a function
33
+ declarator that includes a *trailing-return-type* [[dcl.fct]].
34
+
35
+ A placeholder type can appear in the *decl-specifier-seq* or
36
+ *type-specifier-seq* in the declared return type of a function
37
+ declarator that declares a function; the return type of the function is
38
+ deduced from non-discarded `return` statements, if any, in the body of
39
+ the function [[stmt.if]].
 
 
40
 
41
  The type of a variable declared using a placeholder type is deduced from
42
  its initializer. This use is allowed in an initializing declaration
43
  [[dcl.init]] of a variable. The placeholder type shall appear as one of
44
+ the *decl-specifier*s in the *decl-specifier-seq* or as one of the
45
+ *type-specifier*s in a *trailing-return-type* that specifies the type
46
+ that replaces such a *decl-specifier*; the *decl-specifier-seq* shall be
47
+ followed by one or more *declarator*s, each of which shall be followed
48
+ by a non-empty *initializer*.
49
 
50
  [*Example 1*:
51
 
52
  ``` cpp
53
  auto x = 5; // OK, x has type int
54
  const auto *v = &x, u = 6; // OK, v has type const int*, u has type const int
55
  static auto y = 0.0; // OK, y has type double
56
  auto int r; // error: auto is not a storage-class-specifier
57
  auto f() -> int; // OK, f returns int
58
  auto g() { return 0.0; } // OK, g returns double
59
+ auto (*fp)() -> auto = f; // OK
60
  auto h(); // OK, h's return type will be deduced when it is defined
61
  ```
62
 
63
  — *end example*]
64
 
65
  The `auto` *type-specifier* can also be used to introduce a structured
66
  binding declaration [[dcl.struct.bind]].
67
 
68
+ A placeholder type can also be used in the *type-specifier-seq* of the
69
+ *new-type-id* or in the *type-id* of a *new-expression* [[expr.new]]. In
70
+ such a *type-id*, the placeholder type shall appear as one of the
71
+ *type-specifier*s in the *type-specifier-seq* or as one of the
72
+ *type-specifier*s in a *trailing-return-type* that specifies the type
73
+ that replaces such a *type-specifier*.
74
+
75
+ The `auto` *type-specifier* can also be used as the
76
+ *simple-type-specifier* in an explicit type conversion (functional
77
+ notation) [[expr.type.conv]].
78
 
79
  A program that uses a placeholder type in a context not explicitly
80
  allowed in [[dcl.spec.auto]] is ill-formed.
81
 
82
  If the *init-declarator-list* contains more than one *init-declarator*,
 
140
  }
141
  ```
142
 
143
  — *end example*]
144
 
145
+ A result binding never has an undeduced placeholder type
146
+ [[dcl.contract.res]].
147
+
148
+ [*Example 5*:
149
+
150
+ ``` cpp
151
+ auto f()
152
+ post(r : r == 7) // OK
153
+ {
154
+ return 7;
155
+ }
156
+ ```
157
+
158
+ — *end example*]
159
+
160
  Return type deduction for a templated function with a placeholder in its
161
  declared type occurs when the definition is instantiated even if the
162
  function body contains a `return` statement with a non-type-dependent
163
  operand.
164
 
 
166
  template will cause an implicit instantiation. Any errors that arise
167
  from this instantiation are not in the immediate context of the function
168
  type and can result in the program being ill-formed
169
  [[temp.deduct]]. — *end note*]
170
 
171
+ [*Example 6*:
172
 
173
  ``` cpp
174
  template <class T> auto f(T t) { return t; } // return type deduced at instantiation time
175
  typedef decltype(f(1)) fint_t; // instantiates f<int> to deduce return type
176
  template<class T> auto f(T* t) { return *t; }
 
183
  If a function or function template F has a declared return type that
184
  uses a placeholder type, redeclarations or specializations of F shall
185
  use that placeholder type, not a deduced type; otherwise, they shall not
186
  use a placeholder type.
187
 
188
+ [*Example 7*:
189
 
190
  ``` cpp
191
  auto f();
192
  auto f() { return 42; } // return type is int
193
  auto f(); // OK
 
228
  An explicit instantiation declaration [[temp.explicit]] does not cause
229
  the instantiation of an entity declared using a placeholder type, but it
230
  also does not prevent that entity from being instantiated as needed to
231
  determine its type.
232
 
233
+ [*Example 8*:
234
 
235
  ``` cpp
236
  template <typename T> auto f(T t) { return t; }
237
  extern template auto f(int); // does not instantiate f<int>
238
  int (*p)(int) = f; // instantiates f<int> to determine its return type, but an explicit
 
278
  single brace-enclosed *assignment-expression* and E is the
279
  *assignment-expression*.
280
  - If the initializer is a parenthesized *expression-list*, the
281
  *expression-list* shall be a single *assignment-expression* and E is
282
  the *assignment-expression*.
283
+ - For a constant template parameter declared with a type that contains a
284
+ placeholder type, `T` is the declared type of the constant template
285
  parameter and E is the corresponding template argument.
286
 
287
  `T` shall not be an array type.
288
 
289
  If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
290
  `auto`, the deduced type T' replacing `T` is determined using the rules
291
  for template argument deduction. If the initialization is
292
  copy-list-initialization, a declaration of `std::initializer_list` shall
293
  precede [[basic.lookup.general]] the *placeholder-type-specifier*.
294
+ Obtain `P` from `T` by replacing the occurrence of *type-constraint*ₒₚₜ
295
+ `auto` either with a new invented type template parameter `U` or, if the
296
+ initialization is copy-list-initialization, with
297
+ `std::initializer_list<U>`. Deduce a value for `U` using the rules of
298
+ template argument deduction from a function call [[temp.deduct.call]],
299
+ where `P` is a function template parameter type and the corresponding
300
+ argument is E. If the deduction fails, the declaration is ill-formed.
301
+ Otherwise, T' is obtained by substituting the deduced `U` into `P`.
 
302
 
303
+ [*Example 9*:
304
 
305
  ``` cpp
306
  auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
307
  auto x2 = { 1, 2.0 }; // error: cannot deduce element type
308
  auto x3{ 1, 2 }; // error: not a single element
 
310
  auto x5{ 3 }; // decltype(x5) is int
311
  ```
312
 
313
  — *end example*]
314
 
315
+ [*Example 10*:
316
 
317
  ``` cpp
318
  const auto &i = expr;
319
  ```
320
 
 
330
  If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
331
  `decltype(auto)`, `T` shall be the placeholder alone. The type deduced
332
  for `T` is determined as described in  [[dcl.type.decltype]], as though
333
  E had been the operand of the `decltype`.
334
 
335
+ [*Example 11*:
336
 
337
  ``` cpp
338
  int i;
339
  int&& f();
340
  auto x2a(i); // decltype(x2a) is int