From Jason Turner

[dcl.type]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpdzqdi1xo/{from.md → to.md} +346 -190
tmp/tmpdzqdi1xo/{from.md → to.md} RENAMED
@@ -2,17 +2,10 @@
2
 
3
  The type-specifiers are
4
 
5
  ``` bnf
6
  type-specifier:
7
- trailing-type-specifier
8
- class-specifier
9
- enum-specifier
10
- ```
11
-
12
- ``` bnf
13
- trailing-type-specifier:
14
  simple-type-specifier
15
  elaborated-type-specifier
16
  typename-specifier
17
  cv-qualifier
18
  ```
@@ -22,74 +15,91 @@ type-specifier-seq:
22
  type-specifier attribute-specifier-seqₒₚₜ
23
  type-specifier type-specifier-seq
24
  ```
25
 
26
  ``` bnf
27
- trailing-type-specifier-seq:
28
- trailing-type-specifier attribute-specifier-seqₒₚₜ
29
- trailing-type-specifier trailing-type-specifier-seq
 
 
 
 
 
 
 
30
  ```
31
 
32
  The optional *attribute-specifier-seq* in a *type-specifier-seq* or a
33
- *trailing-type-specifier-seq* appertains to the type denoted by the
34
- preceding *type-specifier*s ([[dcl.meaning]]). The
35
- *attribute-specifier-seq* affects the type only for the declaration it
36
- appears in, not other declarations involving the same type.
 
37
 
38
- As a general rule, at most one *type-specifier* is allowed in the
39
- complete *decl-specifier-seq* of a *declaration* or in a
40
- *type-specifier-seq* or *trailing-type-specifier-seq*. The only
41
- exceptions to this rule are the following:
 
42
 
43
  - `const` can be combined with any type specifier except itself.
44
  - `volatile` can be combined with any type specifier except itself.
45
  - `signed` or `unsigned` can be combined with `char`, `long`, `short`,
46
  or `int`.
47
  - `short` or `long` can be combined with `int`.
48
  - `long` can be combined with `double`.
49
  - `long` can be combined with `long`.
50
 
51
  Except in a declaration of a constructor, destructor, or conversion
52
- function, at least one *type-specifier* that is not a *cv-qualifier*
53
- shall appear in a complete *type-specifier-seq* or a complete
54
- *decl-specifier-seq*.[^3] A *type-specifier-seq* shall not define a
55
- class or enumeration unless it appears in the *type-id* of an
56
- *alias-declaration* ([[dcl.typedef]]) that is not the *declaration* of
57
- a *template-declaration*.
58
 
59
- *enum-specifier*s, *class-specifier*s, and *typename-specifier*s are
60
- discussed in [[dcl.enum]], Clause  [[class]], and [[temp.res]],
61
- respectively. The remaining *type-specifier*s are discussed in the rest
62
- of this section.
63
 
64
- #### The *cv-qualifiers* <a id="dcl.type.cv">[[dcl.type.cv]]</a>
65
 
66
- There are two *cv-qualifiers*, `const` and `volatile`. Each
67
  *cv-qualifier* shall appear at most once in a *cv-qualifier-seq*. If a
68
  *cv-qualifier* appears in a *decl-specifier-seq*, the
69
- *init-declarator-list* of the declaration shall not be empty.
70
- [[basic.type.qualifier]] and [[dcl.fct]] describe how cv-qualifiers
71
- affect object and function types. Redundant cv-qualifications are
72
- ignored. For example, these could be introduced by typedefs.
73
-
74
- Declaring a variable `const` can affect its linkage ([[dcl.stc]]) and
75
- its usability in constant expressions ([[expr.const]]). As described
76
- in  [[dcl.init]], the definition of an object or subobject of
77
- const-qualified type must specify an initializer or be subject to
78
- default-initialization.
 
 
 
 
 
 
79
 
80
  A pointer or reference to a cv-qualified type need not actually point or
81
  refer to a cv-qualified object, but it is treated as if it does; a
82
  const-qualified access path cannot be used to modify an object even if
83
  the object referenced is a non-const object and can be modified through
84
- some other access path. Cv-qualifiers are supported by the type system
85
- so that they cannot be subverted without casting ([[expr.const.cast]]).
 
 
 
86
 
87
  Except that any class member declared `mutable` ([[dcl.stc]]) can be
88
  modified, any attempt to modify a `const` object during its lifetime (
89
  [[basic.life]]) results in undefined behavior.
90
 
 
 
91
  ``` cpp
92
  const int ci = 3; // cv-qualified (initialized as required)
93
  ci = 4; // ill-formed: attempt to modify const
94
 
95
  int i = 2; // not cv-qualified
@@ -104,11 +114,11 @@ ip = const_cast<int*>(cip); // cast needed to convert const int* to int*
104
  const int* ciq = new const int (3); // initialized as required
105
  int* iq = const_cast<int*>(ciq); // cast required
106
  *iq = 4; // undefined: modifies a const object
107
  ```
108
 
109
- For another example
110
 
111
  ``` cpp
112
  struct X {
113
  mutable int i;
114
  int j;
@@ -124,31 +134,35 @@ y.x.j++; // ill-formed: const-qualified member modified
124
  Y* p = const_cast<Y*>(&y); // cast away const-ness of y
125
  p->x.i = 99; // well-formed: mutable member can be modified
126
  p->x.j = 99; // undefined: modifies a const member
127
  ```
128
 
129
- What constitutes an access to an object that has volatile-qualified type
130
- is implementation-defined. If an attempt is made to refer to an object
131
- defined with a volatile-qualified type through the use of a glvalue with
132
- a non-volatile-qualified type, the program behavior is undefined.
133
 
134
- `volatile` is a hint to the implementation to avoid aggressive
135
- optimization involving the object because the value of the object might
136
- be changed by means undetectable by an implementation. Furthermore, for
137
- some implementations, `volatile` might indicate that special hardware
138
- instructions are required to access the object. See  [[intro.execution]]
139
- for detailed semantics. In general, the semantics of `volatile` are
140
- intended to be the same in C++as they are in C.
 
 
 
 
 
 
141
 
142
  #### Simple type specifiers <a id="dcl.type.simple">[[dcl.type.simple]]</a>
143
 
144
  The simple type specifiers are
145
 
146
  ``` bnf
147
  simple-type-specifier:
148
  nested-name-specifierₒₚₜ type-name
149
  nested-name-specifier 'template' simple-template-id
 
150
  'char'
151
  'char16_t'
152
  'char32_t'
153
  'wchar_t'
154
  'bool'
@@ -176,23 +190,28 @@ type-name:
176
  decltype-specifier:
177
  'decltype' '(' expression ')'
178
  'decltype' '(' 'auto' ')'
179
  ```
180
 
181
- The `auto` specifier is a placeholder for a type to be deduced (
182
- [[dcl.spec.auto]]). The other *simple-type-specifier*s specify either a
 
 
 
 
183
  previously-declared type, a type determined from an expression, or one
184
  of the fundamental types ([[basic.fundamental]]). Table 
185
  [[tab:simple.type.specifiers]] summarizes the valid combinations of
186
  *simple-type-specifier*s and the types they specify.
187
 
188
  **Table: *simple-type-specifier*{s} and the types they specify** <a id="tab:simple.type.specifiers">[tab:simple.type.specifiers]</a>
189
 
190
- | | |
191
  | ---------------------- | -------------------------------------- |
192
  | *type-name* | the type named |
193
  | *simple-template-id* | the type as defined in~ [[temp.names]] |
 
194
  | char | ``char'' |
195
  | unsigned char | ``unsigned char'' |
196
  | signed char | ``signed char'' |
197
  | char16_t | ``char16_t'' |
198
  | char32_t | ``char32_t'' |
@@ -224,90 +243,109 @@ of the fundamental types ([[basic.fundamental]]). Table 
224
  | float | ``float'' |
225
  | double | ``double'' |
226
  | long double | ``long double'' |
227
  | void | ``void'' |
228
  | auto | placeholder for a type to be deduced |
 
229
  | decltype(*expression*) | the type as defined below |
230
 
231
 
232
- When multiple *simple-type-specifiers* are allowed, they can be freely
233
- intermixed with other *decl-specifiers* in any order. It is
234
- implementation-defined whether objects of `char` type are represented as
235
- signed or unsigned quantities. The `signed` specifier forces `char`
236
- objects to be signed; it is redundant in other contexts.
 
 
237
 
238
  For an expression `e`, the type denoted by `decltype(e)` is defined as
239
  follows:
240
 
241
- - if `e` is an unparenthesized *id-expression* or an unparenthesized
242
- class member access ([[expr.ref]]), `decltype(e)` is the type of the
243
- entity named by `e`. If there is no such entity, or if `e` names a set
244
- of overloaded functions, the program is ill-formed;
 
 
 
245
  - otherwise, if `e` is an xvalue, `decltype(e)` is `T&&`, where `T` is
246
  the type of `e`;
247
  - otherwise, if `e` is an lvalue, `decltype(e)` is `T&`, where `T` is
248
  the type of `e`;
249
  - otherwise, `decltype(e)` is the type of `e`.
250
 
251
  The operand of the `decltype` specifier is an unevaluated operand
252
  (Clause  [[expr]]).
253
 
 
 
254
  ``` cpp
255
  const int&& foo();
256
  int i;
257
  struct A { double x; };
258
  const A* a = new A();
259
- decltype(foo()) x1 = 0; // type is const int&&
260
  decltype(i) x2; // type is int
261
  decltype(a->x) x3; // type is double
262
  decltype((a->x)) x4 = x3; // type is const double&
263
  ```
264
 
265
- The rules for determining types involving `decltype(auto)` are specified
266
- in  [[dcl.spec.auto]].
267
-
268
- in the case where the operand of a *decltype-specifier* is a function
269
- call and the return type of the function is a class type, a special
270
- rule ([[expr.call]]) ensures that the return type is not required to be
271
- complete (as it would be if the call appeared in a sub-expression or
272
- outside of a *decltype-specifier*). In this context, the common purpose
273
- of writing the expression is merely to refer to its type. In that sense,
274
- a *decltype-specifier* is analogous to a use of a *typedef-name*, so the
275
- usual reasons for requiring a complete type do not apply. In particular,
276
- it is not necessary to allocate storage for a temporary object or to
277
- enforce the semantic constraints associated with invoking the type’s
278
- destructor.
 
 
 
 
 
 
 
 
 
 
279
 
280
  ``` cpp
281
  template<class T> struct A { ~A() = delete; };
282
  template<class T> auto h()
283
  -> A<T>;
284
  template<class T> auto i(T) // identity
285
  -> T;
286
  template<class T> auto f(T) // #1
287
- -> decltype(i(h<T>())); // forces completion of A<T> and implicitly uses
288
- // A<T>::~A() for the temporary introduced by the
289
- // use of h(). (A temporary is not introduced
290
- // as a result of the use of i().)
291
  template<class T> auto f(T) // #2
292
  -> void;
293
  auto g() -> void {
294
- f(42); // OK: calls #2. (#1 is not a viable candidate: type
295
- // deduction fails~([temp.deduct]) because A<int>::~{A()}
296
- // is implicitly used in its decltype-specifier)
297
  }
298
  template<class T> auto q(T)
299
- -> decltype((h<T>())); // does not force completion of A<T>; A<T>::~A() is
300
- // not implicitly used within the context of this decltype-specifier
301
  void r() {
302
- q(42); // Error: deduction against q succeeds, so overload resolution
303
- // selects the specialization ``q(T) -> decltype((h<T>())) [with T=int]''.
304
  // The return type is A<int>, so a temporary is introduced and its
305
  // destructor is used, so the program is ill-formed.
306
  }
307
  ```
308
 
 
 
309
  #### Elaborated type specifiers <a id="dcl.type.elab">[[dcl.type.elab]]</a>
310
 
311
  ``` bnf
312
  elaborated-type-specifier:
313
  class-key attribute-specifier-seqₒₚₜ nested-name-specifierₒₚₜ identifier
@@ -341,20 +379,26 @@ class whenever it is named.
341
  resolves to a *class-name* or *enum-name*, the
342
  *elaborated-type-specifier* introduces it into the declaration the same
343
  way a *simple-type-specifier* introduces its *type-name*. If the
344
  *identifier* resolves to a *typedef-name* or the *simple-template-id*
345
  resolves to an alias template specialization, the
346
- *elaborated-type-specifier* is ill-formed. This implies that, within a
347
- class template with a template *type-parameter* `T`, the declaration
 
 
 
 
348
 
349
  ``` cpp
350
  friend class T;
351
  ```
352
 
353
  is ill-formed. However, the similar declaration `friend T;` is allowed (
354
  [[class.friend]]).
355
 
 
 
356
  The *class-key* or `enum` keyword present in the
357
  *elaborated-type-specifier* shall agree in kind with the declaration to
358
  which the name in the *elaborated-type-specifier* refers. This rule also
359
  applies to the form of *elaborated-type-specifier* that declares a
360
  *class-name* or `friend` class since it can be construed as referring to
@@ -363,164 +407,130 @@ the `enum` keyword shall be used to refer to an enumeration (
363
  [[dcl.enum]]), the `union` *class-key* shall be used to refer to a union
364
  (Clause  [[class]]), and either the `class` or `struct` *class-key*
365
  shall be used to refer to a class (Clause  [[class]]) declared using the
366
  `class` or `struct` *class-key*.
367
 
 
 
368
  ``` cpp
369
  enum class E { a, b };
370
  enum E x = E::a; // OK
371
  ```
372
 
373
- #### `auto` specifier <a id="dcl.spec.auto">[[dcl.spec.auto]]</a>
374
 
375
- The `auto` and `decltype(auto)` *type-specifier*s designate a
376
- placeholder type that will be replaced later, either by deduction from
377
- an initializer or by explicit specification with a
378
- *trailing-return-type*. The `auto` *type-specifier* is also used to
379
- signify that a lambda is a generic lambda.
 
 
 
 
380
 
381
  The placeholder type can appear with a function declarator in the
382
  *decl-specifier-seq*, *type-specifier-seq*, *conversion-function-id*, or
383
  *trailing-return-type*, in any context where such a declarator is valid.
384
  If the function declarator includes a *trailing-return-type* (
385
- [[dcl.fct]]), that specifies the declared return type of the function.
386
- If the declared return type of the function contains a placeholder type,
387
- the return type of the function is deduced from `return` statements in
388
- the body of the function, if any.
 
 
389
 
390
  If the `auto` *type-specifier* appears as one of the *decl-specifier*s
391
  in the *decl-specifier-seq* of a *parameter-declaration* of a
392
  *lambda-expression*, the lambda is a *generic lambda* (
393
- [[expr.prim.lambda]]).
 
 
394
 
395
  ``` cpp
396
  auto glambda = [](int i, auto a) { return i; }; // OK: a generic lambda
397
  ```
398
 
 
 
399
  The type of a variable declared using `auto` or `decltype(auto)` is
400
- deduced from its initializer. This use is allowed when declaring
401
- variables in a block ([[stmt.block]]), in namespace scope (
402
- [[basic.scope.namespace]]), and in a  ([[stmt.for]]). `auto` or
403
- `decltype(auto)` shall appear as one of the *decl-specifier*s in the
404
- *decl-specifier-seq* and the *decl-specifier-seq* shall be followed by
405
- one or more *init-declarator*s, each of which shall have a non-empty
406
  *initializer*. In an *initializer* of the form
407
 
408
  ``` cpp
409
  ( expression-list )
410
  ```
411
 
412
  the *expression-list* shall be a single *assignment-expression*.
413
 
 
 
414
  ``` cpp
415
  auto x = 5; // OK: x has type int
416
  const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int
417
  static auto y = 0.0; // OK: y has type double
418
  auto int r; // error: auto is not a storage-class-specifier
419
  auto f() -> int; // OK: f returns int
420
  auto g() { return 0.0; } // OK: g returns double
421
  auto h(); // OK: h's return type will be deduced when it is defined
422
  ```
423
 
424
- A placeholder type can also be used in declaring a variable in the of a
425
- selection statement ([[stmt.select]]) or an iteration statement (
426
- [[stmt.iter]]), in the in the or of a  ([[expr.new]]), in a
427
- *for-range-declaration*, and in declaring a static data member with a
428
- *brace-or-equal-initializer* that appears within the of a class
429
- definition ([[class.static.data]]).
430
 
431
  A program that uses `auto` or `decltype(auto)` in a context not
432
  explicitly allowed in this section is ill-formed.
433
 
434
- When a variable declared using a placeholder type is initialized, or a
435
- `return` statement occurs in a function declared with a return type that
436
- contains a placeholder type, the deduced return type or variable type is
437
- determined from the type of its initializer. In the case of a `return`
438
- with no operand, the initializer is considered to be `void()`. Let `T`
439
- be the declared type of the variable or return type of the function. If
440
- the placeholder is the `auto` *type-specifier*, the deduced type is
441
- determined using the rules for template argument deduction. If the
442
- deduction is for a `return` statement and the initializer is a
443
- *braced-init-list* ([[dcl.init.list]]), the program is ill-formed.
444
- Otherwise, obtain `P` from `T` by replacing the occurrences of `auto`
445
- with either a new invented type template parameter `U` or, if the
446
- initializer is a *braced-init-list*, with `std::initializer_list<U>`.
447
- Deduce a value for `U` using the rules of template argument deduction
448
- from a function call ([[temp.deduct.call]]), where `P` is a function
449
- template parameter type and the initializer is the corresponding
450
- argument. If the deduction fails, the declaration is ill-formed.
451
- Otherwise, the type deduced for the variable or return type is obtained
452
- by substituting the deduced `U` into `P`.
453
-
454
- ``` cpp
455
- auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
456
- auto x2 = { 1, 2.0 }; // error: cannot deduce element type
457
- ```
458
-
459
- ``` cpp
460
- const auto &i = expr;
461
- ```
462
-
463
- The type of `i` is the deduced type of the parameter `u` in the call
464
- `f(expr)` of the following invented function template:
465
-
466
- ``` cpp
467
- template <class U> void f(const U& u);
468
- ```
469
-
470
- If the placeholder is the `decltype(auto)` *type-specifier*, the
471
- declared type of the variable or return type of the function shall be
472
- the placeholder alone. The type deduced for the variable or return type
473
- is determined as described in  [[dcl.type.simple]], as though the
474
- initializer had been the operand of the `decltype`.
475
-
476
- ``` cpp
477
- int i;
478
- int&& f();
479
- auto x3a = i; // decltype(x3a) is int
480
- decltype(auto) x3d = i; // decltype(x3d) is int
481
- auto x4a = (i); // decltype(x4a) is int
482
- decltype(auto) x4d = (i); // decltype(x4d) is int&
483
- auto x5a = f(); // decltype(x5a) is int
484
- decltype(auto) x5d = f(); // decltype(x5d) is int&&
485
- auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
486
- decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
487
- auto *x7a = &i; // decltype(x7a) is int*
488
- decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)
489
- ```
490
-
491
  If the *init-declarator-list* contains more than one *init-declarator*,
492
  they shall all form declarations of variables. The type of each declared
493
- variable is determined as described above, and if the type that replaces
494
- the placeholder type is not the same in each deduction, the program is
495
- ill-formed.
 
 
496
 
497
  ``` cpp
498
  auto x = 5, *y = &x; // OK: auto is int
499
  auto a = 5, b = { 1, 2 }; // error: different types for auto
500
  ```
501
 
 
 
502
  If a function with a declared return type that contains a placeholder
503
- type has multiple `return` statements, the return type is deduced for
504
- each `return` statement. If the type deduced is not the same in each
505
- deduction, the program is ill-formed.
506
 
507
  If a function with a declared return type that uses a placeholder type
508
- has no `return` statements, the return type is deduced as though from a
509
- `return` statement with no operand at the closing brace of the function
510
- body.
 
 
511
 
512
  ``` cpp
513
  auto f() { } // OK, return type is void
514
  auto* g() { } // error, cannot deduce auto* from void()
515
  ```
516
 
 
 
517
  If the type of an entity with an undeduced placeholder type is needed to
518
  determine the type of an expression, the program is ill-formed. Once a
519
- `return` statement has been seen in a function, however, the return type
520
- deduced from that statement can be used in the rest of the function,
521
- including in other `return` statements.
 
 
522
 
523
  ``` cpp
524
  auto n = n; // error, n's type is unknown
525
  auto f();
526
  void g() { &f; } // error, f's return type is unknown
@@ -530,30 +540,41 @@ auto sum(int i) {
530
  else
531
  return sum(i-1)+i; // OK, sum's return type has been deduced
532
  }
533
  ```
534
 
 
 
535
  Return type deduction for a function template with a placeholder in its
536
  declared type occurs when the definition is instantiated even if the
537
  function body contains a `return` statement with a non-type-dependent
538
- operand. Therefore, any use of a specialization of the function template
539
- will cause an implicit instantiation. Any errors that arise from this
540
- instantiation are not in the immediate context of the function type and
541
- can result in the program being ill-formed.
 
 
 
 
 
542
 
543
  ``` cpp
544
  template <class T> auto f(T t) { return t; } // return type deduced at instantiation time
545
  typedef decltype(f(1)) fint_t; // instantiates f<int> to deduce return type
546
  template<class T> auto f(T* t) { return *t; }
547
  void g() { int (*p)(int*) = &f; } // instantiates both fs to determine return types,
548
  // chooses second
549
  ```
550
 
 
 
551
  Redeclarations or specializations of a function or function template
552
  with a declared return type that uses a placeholder type shall also use
553
  that placeholder, not a deduced type.
554
 
 
 
555
  ``` cpp
556
  auto f();
557
  auto f() { return 42; } // return type is int
558
  auto f(); // OK
559
  int f(); // error, cannot be overloaded with auto f()
@@ -574,20 +595,155 @@ template <typename T> struct A {
574
  friend T frf(T);
575
  };
576
  auto frf(int i) { return i; } // not a friend of A<int>
577
  ```
578
 
 
 
579
  A function declared with a return type that uses a placeholder type
580
  shall not be `virtual` ([[class.virtual]]).
581
 
582
  An explicit instantiation declaration ([[temp.explicit]]) does not
583
  cause the instantiation of an entity declared using a placeholder type,
584
  but it also does not prevent that entity from being instantiated as
585
  needed to determine its type.
586
 
 
 
587
  ``` cpp
588
  template <typename T> auto f(T t) { return t; }
589
  extern template auto f(int); // does not instantiate f<int>
590
  int (*p)(int) = f; // instantiates f<int> to determine its return type, but an explicit
591
  // instantiation definition is still required somewhere in the program
592
  ```
593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  The type-specifiers are
4
 
5
  ``` bnf
6
  type-specifier:
 
 
 
 
 
 
 
7
  simple-type-specifier
8
  elaborated-type-specifier
9
  typename-specifier
10
  cv-qualifier
11
  ```
 
15
  type-specifier attribute-specifier-seqₒₚₜ
16
  type-specifier type-specifier-seq
17
  ```
18
 
19
  ``` bnf
20
+ defining-type-specifier:
21
+ type-specifier
22
+ class-specifier
23
+ enum-specifier
24
+ ```
25
+
26
+ ``` bnf
27
+ defining-type-specifier-seq:
28
+ defining-type-specifier attribute-specifier-seqₒₚₜ
29
+ defining-type-specifier defining-type-specifier-seq
30
  ```
31
 
32
  The optional *attribute-specifier-seq* in a *type-specifier-seq* or a
33
+ *defining-type-specifier-seq* appertains to the type denoted by the
34
+ preceding *type-specifier*s or *defining-type-specifier*s (
35
+ [[dcl.meaning]]). The *attribute-specifier-seq* affects the type only
36
+ for the declaration it appears in, not other declarations involving the
37
+ same type.
38
 
39
+ As a general rule, at most one *defining-type-specifier* is allowed in
40
+ the complete *decl-specifier-seq* of a *declaration* or in a
41
+ *defining-type-specifier-seq*, and at most one *type-specifier* is
42
+ allowed in a *type-specifier-seq*. The only exceptions to this rule are
43
+ the following:
44
 
45
  - `const` can be combined with any type specifier except itself.
46
  - `volatile` can be combined with any type specifier except itself.
47
  - `signed` or `unsigned` can be combined with `char`, `long`, `short`,
48
  or `int`.
49
  - `short` or `long` can be combined with `int`.
50
  - `long` can be combined with `double`.
51
  - `long` can be combined with `long`.
52
 
53
  Except in a declaration of a constructor, destructor, or conversion
54
+ function, at least one *defining-type-specifier* that is not a
55
+ *cv-qualifier* shall appear in a complete *type-specifier-seq* or a
56
+ complete *decl-specifier-seq*.[^3]
 
 
 
57
 
58
+ [*Note 1*: *enum-specifier*s, *class-specifier*s, and
59
+ *typename-specifier*s are discussed in [[dcl.enum]], Clause  [[class]],
60
+ and [[temp.res]], respectively. The remaining *type-specifier*s are
61
+ discussed in the rest of this section. — *end note*]
62
 
63
+ #### The *cv-qualifier*s <a id="dcl.type.cv">[[dcl.type.cv]]</a>
64
 
65
+ There are two *cv-qualifier*s, `const` and `volatile`. Each
66
  *cv-qualifier* shall appear at most once in a *cv-qualifier-seq*. If a
67
  *cv-qualifier* appears in a *decl-specifier-seq*, the
68
+ *init-declarator-list* or *member-declarator-list* of the declaration
69
+ shall not be empty.
70
+
71
+ [*Note 1*: [[basic.type.qualifier]] and [[dcl.fct]] describe how
72
+ cv-qualifiers affect object and function types. — *end note*]
73
+
74
+ Redundant cv-qualifications are ignored.
75
+
76
+ [*Note 2*: For example, these could be introduced by
77
+ typedefs. — *end note*]
78
+
79
+ [*Note 3*: Declaring a variable `const` can affect its linkage (
80
+ [[dcl.stc]]) and its usability in constant expressions (
81
+ [[expr.const]]). As described in  [[dcl.init]], the definition of an
82
+ object or subobject of const-qualified type must specify an initializer
83
+ or be subject to default-initialization. — *end note*]
84
 
85
  A pointer or reference to a cv-qualified type need not actually point or
86
  refer to a cv-qualified object, but it is treated as if it does; a
87
  const-qualified access path cannot be used to modify an object even if
88
  the object referenced is a non-const object and can be modified through
89
+ some other access path.
90
+
91
+ [*Note 4*: Cv-qualifiers are supported by the type system so that they
92
+ cannot be subverted without casting (
93
+ [[expr.const.cast]]). — *end note*]
94
 
95
  Except that any class member declared `mutable` ([[dcl.stc]]) can be
96
  modified, any attempt to modify a `const` object during its lifetime (
97
  [[basic.life]]) results in undefined behavior.
98
 
99
+ [*Example 1*:
100
+
101
  ``` cpp
102
  const int ci = 3; // cv-qualified (initialized as required)
103
  ci = 4; // ill-formed: attempt to modify const
104
 
105
  int i = 2; // not cv-qualified
 
114
  const int* ciq = new const int (3); // initialized as required
115
  int* iq = const_cast<int*>(ciq); // cast required
116
  *iq = 4; // undefined: modifies a const object
117
  ```
118
 
119
+ For another example,
120
 
121
  ``` cpp
122
  struct X {
123
  mutable int i;
124
  int j;
 
134
  Y* p = const_cast<Y*>(&y); // cast away const-ness of y
135
  p->x.i = 99; // well-formed: mutable member can be modified
136
  p->x.j = 99; // undefined: modifies a const member
137
  ```
138
 
139
+ *end example*]
 
 
 
140
 
141
+ The semantics of an access through a volatile glvalue are
142
+ *implementation-defined*. If an attempt is made to access an object
143
+ defined with a volatile-qualified type through the use of a non-volatile
144
+ glvalue, the behavior is undefined.
145
+
146
+ [*Note 5*: `volatile` is a hint to the implementation to avoid
147
+ aggressive optimization involving the object because the value of the
148
+ object might be changed by means undetectable by an implementation.
149
+ Furthermore, for some implementations, `volatile` might indicate that
150
+ special hardware instructions are required to access the object. See 
151
+ [[intro.execution]] for detailed semantics. In general, the semantics of
152
+ `volatile` are intended to be the same in C++as they are in
153
+ C. — *end note*]
154
 
155
  #### Simple type specifiers <a id="dcl.type.simple">[[dcl.type.simple]]</a>
156
 
157
  The simple type specifiers are
158
 
159
  ``` bnf
160
  simple-type-specifier:
161
  nested-name-specifierₒₚₜ type-name
162
  nested-name-specifier 'template' simple-template-id
163
+ nested-name-specifierₒₚₜ template-name
164
  'char'
165
  'char16_t'
166
  'char32_t'
167
  'wchar_t'
168
  'bool'
 
190
  decltype-specifier:
191
  'decltype' '(' expression ')'
192
  'decltype' '(' 'auto' ')'
193
  ```
194
 
195
+ The *simple-type-specifier* `auto` is a placeholder for a type to be
196
+ deduced ([[dcl.spec.auto]]). A *type-specifier* of the form
197
+ `typename`ₒₚₜ *nested-name-specifier*ₒₚₜ *template-name* is a
198
+ placeholder for a deduced class type ([[dcl.type.class.deduct]]). The
199
+ *template-name* shall name a class template that is not an
200
+ injected-class-name. The other *simple-type-specifier*s specify either a
201
  previously-declared type, a type determined from an expression, or one
202
  of the fundamental types ([[basic.fundamental]]). Table 
203
  [[tab:simple.type.specifiers]] summarizes the valid combinations of
204
  *simple-type-specifier*s and the types they specify.
205
 
206
  **Table: *simple-type-specifier*{s} and the types they specify** <a id="tab:simple.type.specifiers">[tab:simple.type.specifiers]</a>
207
 
208
+ | Specifier(s) | Type |
209
  | ---------------------- | -------------------------------------- |
210
  | *type-name* | the type named |
211
  | *simple-template-id* | the type as defined in~ [[temp.names]] |
212
+ | *template-name* | placeholder for a type to be deduced |
213
  | char | ``char'' |
214
  | unsigned char | ``unsigned char'' |
215
  | signed char | ``signed char'' |
216
  | char16_t | ``char16_t'' |
217
  | char32_t | ``char32_t'' |
 
243
  | float | ``float'' |
244
  | double | ``double'' |
245
  | long double | ``long double'' |
246
  | void | ``void'' |
247
  | auto | placeholder for a type to be deduced |
248
+ | decltype(auto) | placeholder for a type to be deduced |
249
  | decltype(*expression*) | the type as defined below |
250
 
251
 
252
+ When multiple *simple-type-specifier*s are allowed, they can be freely
253
+ intermixed with other *decl-specifier*s in any order.
254
+
255
+ [*Note 1*: It is *implementation-defined* whether objects of `char`
256
+ type are represented as signed or unsigned quantities. The `signed`
257
+ specifier forces `char` objects to be signed; it is redundant in other
258
+ contexts. — *end note*]
259
 
260
  For an expression `e`, the type denoted by `decltype(e)` is defined as
261
  follows:
262
 
263
+ - if `e` is an unparenthesized *id-expression* naming a structured
264
+ binding ([[dcl.struct.bind]]), `decltype(e)` is the referenced type
265
+ as given in the specification of the structured binding declaration;
266
+ - otherwise, if `e` is an unparenthesized *id-expression* or an
267
+ unparenthesized class member access ([[expr.ref]]), `decltype(e)` is
268
+ the type of the entity named by `e`. If there is no such entity, or if
269
+ `e` names a set of overloaded functions, the program is ill-formed;
270
  - otherwise, if `e` is an xvalue, `decltype(e)` is `T&&`, where `T` is
271
  the type of `e`;
272
  - otherwise, if `e` is an lvalue, `decltype(e)` is `T&`, where `T` is
273
  the type of `e`;
274
  - otherwise, `decltype(e)` is the type of `e`.
275
 
276
  The operand of the `decltype` specifier is an unevaluated operand
277
  (Clause  [[expr]]).
278
 
279
+ [*Example 1*:
280
+
281
  ``` cpp
282
  const int&& foo();
283
  int i;
284
  struct A { double x; };
285
  const A* a = new A();
286
+ decltype(foo()) x1 = 17; // type is const int&&
287
  decltype(i) x2; // type is int
288
  decltype(a->x) x3; // type is double
289
  decltype((a->x)) x4 = x3; // type is const double&
290
  ```
291
 
292
+ *end example*]
293
+
294
+ [*Note 2*: The rules for determining types involving `decltype(auto)`
295
+ are specified in  [[dcl.spec.auto]]. *end note*]
296
+
297
+ If the operand of a *decltype-specifier* is a prvalue, the temporary
298
+ materialization conversion is not applied ([[conv.rval]]) and no result
299
+ object is provided for the prvalue. The type of the prvalue may be
300
+ incomplete.
301
+
302
+ [*Note 3*: As a result, storage is not allocated for the prvalue and it
303
+ is not destroyed. Thus, a class type is not instantiated as a result of
304
+ being the type of a function call in this context. In this context, the
305
+ common purpose of writing the expression is merely to refer to its type.
306
+ In that sense, a *decltype-specifier* is analogous to a use of a
307
+ *typedef-name*, so the usual reasons for requiring a complete type do
308
+ not apply. In particular, it is not necessary to allocate storage for a
309
+ temporary object or to enforce the semantic constraints associated with
310
+ invoking the type’s destructor. — *end note*]
311
+
312
+ [*Note 4*: Unlike the preceding rule, parentheses have no special
313
+ meaning in this context. — *end note*]
314
+
315
+ [*Example 2*:
316
 
317
  ``` cpp
318
  template<class T> struct A { ~A() = delete; };
319
  template<class T> auto h()
320
  -> A<T>;
321
  template<class T> auto i(T) // identity
322
  -> T;
323
  template<class T> auto f(T) // #1
324
+ -> decltype(i(h<T>())); // forces completion of A<T> and implicitly uses A<T>::~A()
325
+ // for the temporary introduced by the use of h().
326
+ // (A temporary is not introduced as a result of the use of i().)
 
327
  template<class T> auto f(T) // #2
328
  -> void;
329
  auto g() -> void {
330
+ f(42); // OK: calls #2. (#1 is not a viable candidate: type deduction
331
+ // fails~([temp.deduct]) because A<int>::~{A()} is implicitly used in its
332
+ // decltype-specifier)
333
  }
334
  template<class T> auto q(T)
335
+ -> decltype((h<T>())); // does not force completion of A<T>; A<T>::~A() is not implicitly
336
+ // used within the context of this decltype-specifier
337
  void r() {
338
+ q(42); // Error: deduction against q succeeds, so overload resolution selects
339
+ // the specialization ``q(T) -> decltype((h<T>())) [with T=int]''.
340
  // The return type is A<int>, so a temporary is introduced and its
341
  // destructor is used, so the program is ill-formed.
342
  }
343
  ```
344
 
345
+ — *end example*]
346
+
347
  #### Elaborated type specifiers <a id="dcl.type.elab">[[dcl.type.elab]]</a>
348
 
349
  ``` bnf
350
  elaborated-type-specifier:
351
  class-key attribute-specifier-seqₒₚₜ nested-name-specifierₒₚₜ identifier
 
379
  resolves to a *class-name* or *enum-name*, the
380
  *elaborated-type-specifier* introduces it into the declaration the same
381
  way a *simple-type-specifier* introduces its *type-name*. If the
382
  *identifier* resolves to a *typedef-name* or the *simple-template-id*
383
  resolves to an alias template specialization, the
384
+ *elaborated-type-specifier* is ill-formed.
385
+
386
+ [*Note 1*:
387
+
388
+ This implies that, within a class template with a template
389
+ *type-parameter* `T`, the declaration
390
 
391
  ``` cpp
392
  friend class T;
393
  ```
394
 
395
  is ill-formed. However, the similar declaration `friend T;` is allowed (
396
  [[class.friend]]).
397
 
398
+ — *end note*]
399
+
400
  The *class-key* or `enum` keyword present in the
401
  *elaborated-type-specifier* shall agree in kind with the declaration to
402
  which the name in the *elaborated-type-specifier* refers. This rule also
403
  applies to the form of *elaborated-type-specifier* that declares a
404
  *class-name* or `friend` class since it can be construed as referring to
 
407
  [[dcl.enum]]), the `union` *class-key* shall be used to refer to a union
408
  (Clause  [[class]]), and either the `class` or `struct` *class-key*
409
  shall be used to refer to a class (Clause  [[class]]) declared using the
410
  `class` or `struct` *class-key*.
411
 
412
+ [*Example 1*:
413
+
414
  ``` cpp
415
  enum class E { a, b };
416
  enum E x = E::a; // OK
417
  ```
418
 
419
+ *end example*]
420
 
421
+ #### The `auto` specifier <a id="dcl.spec.auto">[[dcl.spec.auto]]</a>
422
+
423
+ The `auto` and `decltype(auto)` *type-specifier*s are used to designate
424
+ a placeholder type that will be replaced later by deduction from an
425
+ initializer. The `auto` *type-specifier* is also used to introduce a
426
+ function type having a *trailing-return-type* or to signify that a
427
+ lambda is a generic lambda ([[expr.prim.lambda.closure]]). The `auto`
428
+ *type-specifier* is also used to introduce a structured binding
429
+ declaration ([[dcl.struct.bind]]).
430
 
431
  The placeholder type can appear with a function declarator in the
432
  *decl-specifier-seq*, *type-specifier-seq*, *conversion-function-id*, or
433
  *trailing-return-type*, in any context where such a declarator is valid.
434
  If the function declarator includes a *trailing-return-type* (
435
+ [[dcl.fct]]), that *trailing-return-type* specifies the declared return
436
+ type of the function. Otherwise, the function declarator shall declare a
437
+ function. If the declared return type of the function contains a
438
+ placeholder type, the return type of the function is deduced from
439
+ non-discarded `return` statements, if any, in the body of the function (
440
+ [[stmt.if]]).
441
 
442
  If the `auto` *type-specifier* appears as one of the *decl-specifier*s
443
  in the *decl-specifier-seq* of a *parameter-declaration* of a
444
  *lambda-expression*, the lambda is a *generic lambda* (
445
+ [[expr.prim.lambda.closure]]).
446
+
447
+ [*Example 1*:
448
 
449
  ``` cpp
450
  auto glambda = [](int i, auto a) { return i; }; // OK: a generic lambda
451
  ```
452
 
453
+ — *end example*]
454
+
455
  The type of a variable declared using `auto` or `decltype(auto)` is
456
+ deduced from its initializer. This use is allowed in an initializing
457
+ declaration ([[dcl.init]]) of a variable. `auto` or `decltype(auto)`
458
+ shall appear as one of the *decl-specifier*s in the *decl-specifier-seq*
459
+ and the *decl-specifier-seq* shall be followed by one or more
460
+ *declarator*s, each of which shall be followed by a non-empty
 
461
  *initializer*. In an *initializer* of the form
462
 
463
  ``` cpp
464
  ( expression-list )
465
  ```
466
 
467
  the *expression-list* shall be a single *assignment-expression*.
468
 
469
+ [*Example 2*:
470
+
471
  ``` cpp
472
  auto x = 5; // OK: x has type int
473
  const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int
474
  static auto y = 0.0; // OK: y has type double
475
  auto int r; // error: auto is not a storage-class-specifier
476
  auto f() -> int; // OK: f returns int
477
  auto g() { return 0.0; } // OK: g returns double
478
  auto h(); // OK: h's return type will be deduced when it is defined
479
  ```
480
 
481
+ *end example*]
482
+
483
+ A placeholder type can also be used in the *type-specifier-seq* in the
484
+ *new-type-id* or *type-id* of a *new-expression* ([[expr.new]]) and as
485
+ a *decl-specifier* of the *parameter-declaration*'s *decl-specifier-seq*
486
+ in a *template-parameter* ([[temp.param]]).
487
 
488
  A program that uses `auto` or `decltype(auto)` in a context not
489
  explicitly allowed in this section is ill-formed.
490
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  If the *init-declarator-list* contains more than one *init-declarator*,
492
  they shall all form declarations of variables. The type of each declared
493
+ variable is determined by placeholder type deduction (
494
+ [[dcl.type.auto.deduct]]), and if the type that replaces the placeholder
495
+ type is not the same in each deduction, the program is ill-formed.
496
+
497
+ [*Example 3*:
498
 
499
  ``` cpp
500
  auto x = 5, *y = &x; // OK: auto is int
501
  auto a = 5, b = { 1, 2 }; // error: different types for auto
502
  ```
503
 
504
+ — *end example*]
505
+
506
  If a function with a declared return type that contains a placeholder
507
+ type has multiple non-discarded `return` statements, the return type is
508
+ deduced for each such `return` statement. If the type deduced is not the
509
+ same in each deduction, the program is ill-formed.
510
 
511
  If a function with a declared return type that uses a placeholder type
512
+ has no non-discarded `return` statements, the return type is deduced as
513
+ though from a `return` statement with no operand at the closing brace of
514
+ the function body.
515
+
516
+ [*Example 4*:
517
 
518
  ``` cpp
519
  auto f() { } // OK, return type is void
520
  auto* g() { } // error, cannot deduce auto* from void()
521
  ```
522
 
523
+ — *end example*]
524
+
525
  If the type of an entity with an undeduced placeholder type is needed to
526
  determine the type of an expression, the program is ill-formed. Once a
527
+ non-discarded `return` statement has been seen in a function, however,
528
+ the return type deduced from that statement can be used in the rest of
529
+ the function, including in other `return` statements.
530
+
531
+ [*Example 5*:
532
 
533
  ``` cpp
534
  auto n = n; // error, n's type is unknown
535
  auto f();
536
  void g() { &f; } // error, f's return type is unknown
 
540
  else
541
  return sum(i-1)+i; // OK, sum's return type has been deduced
542
  }
543
  ```
544
 
545
+ — *end example*]
546
+
547
  Return type deduction for a function template with a placeholder in its
548
  declared type occurs when the definition is instantiated even if the
549
  function body contains a `return` statement with a non-type-dependent
550
+ operand.
551
+
552
+ [*Note 1*: Therefore, any use of a specialization of the function
553
+ template will cause an implicit instantiation. Any errors that arise
554
+ from this instantiation are not in the immediate context of the function
555
+ type and can result in the program being ill-formed (
556
+ [[temp.deduct]]). — *end note*]
557
+
558
+ [*Example 6*:
559
 
560
  ``` cpp
561
  template <class T> auto f(T t) { return t; } // return type deduced at instantiation time
562
  typedef decltype(f(1)) fint_t; // instantiates f<int> to deduce return type
563
  template<class T> auto f(T* t) { return *t; }
564
  void g() { int (*p)(int*) = &f; } // instantiates both fs to determine return types,
565
  // chooses second
566
  ```
567
 
568
+ — *end example*]
569
+
570
  Redeclarations or specializations of a function or function template
571
  with a declared return type that uses a placeholder type shall also use
572
  that placeholder, not a deduced type.
573
 
574
+ [*Example 7*:
575
+
576
  ``` cpp
577
  auto f();
578
  auto f() { return 42; } // return type is int
579
  auto f(); // OK
580
  int f(); // error, cannot be overloaded with auto f()
 
595
  friend T frf(T);
596
  };
597
  auto frf(int i) { return i; } // not a friend of A<int>
598
  ```
599
 
600
+ — *end example*]
601
+
602
  A function declared with a return type that uses a placeholder type
603
  shall not be `virtual` ([[class.virtual]]).
604
 
605
  An explicit instantiation declaration ([[temp.explicit]]) does not
606
  cause the instantiation of an entity declared using a placeholder type,
607
  but it also does not prevent that entity from being instantiated as
608
  needed to determine its type.
609
 
610
+ [*Example 8*:
611
+
612
  ``` cpp
613
  template <typename T> auto f(T t) { return t; }
614
  extern template auto f(int); // does not instantiate f<int>
615
  int (*p)(int) = f; // instantiates f<int> to determine its return type, but an explicit
616
  // instantiation definition is still required somewhere in the program
617
  ```
618
 
619
+ — *end example*]
620
+
621
+ ##### Placeholder type deduction <a id="dcl.type.auto.deduct">[[dcl.type.auto.deduct]]</a>
622
+
623
+ *Placeholder type deduction* is the process by which a type containing a
624
+ placeholder type is replaced by a deduced type.
625
+
626
+ A type `T` containing a placeholder type, and a corresponding
627
+ initializer `e`, are determined as follows:
628
+
629
+ - for a non-discarded `return` statement that occurs in a function
630
+ declared with a return type that contains a placeholder type, `T` is
631
+ the declared return type and `e` is the operand of the `return`
632
+ statement. If the `return` statement has no operand, then `e` is
633
+ `void()`;
634
+ - for a variable declared with a type that contains a placeholder type,
635
+ `T` is the declared type of the variable and `e` is the initializer.
636
+ If the initialization is direct-list-initialization, the initializer
637
+ shall be a *braced-init-list* containing only a single
638
+ *assignment-expression* and `e` is the *assignment-expression*;
639
+ - for a non-type template parameter declared with a type that contains a
640
+ placeholder type, `T` is the declared type of the non-type template
641
+ parameter and `e` is the corresponding template argument.
642
+
643
+ In the case of a `return` statement with no operand or with an operand
644
+ of type `void`, `T` shall be either `decltype(auto)` or cv `auto`.
645
+
646
+ If the deduction is for a `return` statement and `e` is a
647
+ *braced-init-list* ([[dcl.init.list]]), the program is ill-formed.
648
+
649
+ If the placeholder is the `auto` *type-specifier*, the deduced type T'
650
+ replacing `T` is determined using the rules for template argument
651
+ deduction. Obtain `P` from `T` by replacing the occurrences of `auto`
652
+ with either a new invented type template parameter `U` or, if the
653
+ initialization is copy-list-initialization, with
654
+ `std::initializer_list<U>`. Deduce a value for `U` using the rules of
655
+ template argument deduction from a function call (
656
+ [[temp.deduct.call]]), where `P` is a function template parameter type
657
+ and the corresponding argument is `e`. If the deduction fails, the
658
+ declaration is ill-formed. Otherwise, T' is obtained by substituting the
659
+ deduced `U` into `P`.
660
+
661
+ [*Example 9*:
662
+
663
+ ``` cpp
664
+ auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
665
+ auto x2 = { 1, 2.0 }; // error: cannot deduce element type
666
+ auto x3{ 1, 2 }; // error: not a single element
667
+ auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
668
+ auto x5{ 3 }; // decltype(x5) is int
669
+ ```
670
+
671
+ — *end example*]
672
+
673
+ [*Example 10*:
674
+
675
+ ``` cpp
676
+ const auto &i = expr;
677
+ ```
678
+
679
+ The type of `i` is the deduced type of the parameter `u` in the call
680
+ `f(expr)` of the following invented function template:
681
+
682
+ ``` cpp
683
+ template <class U> void f(const U& u);
684
+ ```
685
+
686
+ — *end example*]
687
+
688
+ If the placeholder is the `decltype(auto)` *type-specifier*, `T` shall
689
+ be the placeholder alone. The type deduced for `T` is determined as
690
+ described in  [[dcl.type.simple]], as though `e` had been the operand of
691
+ the `decltype`.
692
+
693
+ [*Example 11*:
694
+
695
+ ``` cpp
696
+ int i;
697
+ int&& f();
698
+ auto x2a(i); // decltype(x2a) is int
699
+ decltype(auto) x2d(i); // decltype(x2d) is int
700
+ auto x3a = i; // decltype(x3a) is int
701
+ decltype(auto) x3d = i; // decltype(x3d) is int
702
+ auto x4a = (i); // decltype(x4a) is int
703
+ decltype(auto) x4d = (i); // decltype(x4d) is int&
704
+ auto x5a = f(); // decltype(x5a) is int
705
+ decltype(auto) x5d = f(); // decltype(x5d) is int&&
706
+ auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
707
+ decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
708
+ auto *x7a = &i; // decltype(x7a) is int*
709
+ decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)
710
+ ```
711
+
712
+ — *end example*]
713
+
714
+ #### Deduced class template specialization types <a id="dcl.type.class.deduct">[[dcl.type.class.deduct]]</a>
715
+
716
+ If a placeholder for a deduced class type appears as a *decl-specifier*
717
+ in the *decl-specifier-seq* of an initializing declaration (
718
+ [[dcl.init]]) of a variable, the placeholder is replaced by the return
719
+ type of the function selected by overload resolution for class template
720
+ deduction ([[over.match.class.deduct]]). If the *decl-specifier-seq* is
721
+ followed by an *init-declarator-list* or *member-declarator-list*
722
+ containing more than one *declarator*, the type that replaces the
723
+ placeholder shall be the same in each deduction.
724
+
725
+ A placeholder for a deduced class type can also be used in the
726
+ *type-specifier-seq* in the *new-type-id* or *type-id* of a
727
+ *new-expression* ([[expr.new]]), or as the *simple-type-specifier* in
728
+ an explicit type conversion (functional notation) ([[expr.type.conv]]).
729
+ A placeholder for a deduced class type shall not appear in any other
730
+ context.
731
+
732
+ [*Example 1*:
733
+
734
+ ``` cpp
735
+ template<class T> struct container {
736
+ container(T t) {}
737
+ template<class Iter> container(Iter beg, Iter end);
738
+ };
739
+ template<class Iter>
740
+ container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>;
741
+ std::vector<double> v = { ... };
742
+
743
+ container c(7); // OK, deduces int for T
744
+ auto d = container(v.begin(), v.end()); // OK, deduces double for T
745
+ container e{5, 6}; // error, int is not an iterator
746
+ ```
747
+
748
+ — *end example*]
749
+