- tmp/tmp98pnvehg/{from.md → to.md} +284 -156
tmp/tmp98pnvehg/{from.md → to.md}
RENAMED
|
@@ -27,14 +27,14 @@ The optional *attribute-specifier-seq* in a *decl-specifier-seq*
|
|
| 27 |
appertains to the type determined by the preceding *decl-specifier*s
|
| 28 |
[[dcl.meaning]]. The *attribute-specifier-seq* affects the type only for
|
| 29 |
the declaration it appears in, not other declarations involving the same
|
| 30 |
type.
|
| 31 |
|
| 32 |
-
|
| 33 |
-
*decl-specifier-seq*
|
| 34 |
-
|
| 35 |
-
|
| 36 |
|
| 37 |
If a *type-name* is encountered while parsing a *decl-specifier-seq*, it
|
| 38 |
is interpreted as part of the *decl-specifier-seq* if and only if there
|
| 39 |
is no previous *defining-type-specifier* other than a *cv-qualifier* in
|
| 40 |
the *decl-specifier-seq*. The sequence shall be self-consistent as
|
|
@@ -225,11 +225,13 @@ modification of the mutable class member even though the rest of the
|
|
| 225 |
object is const
|
| 226 |
[[basic.type.qualifier]], [[dcl.type.cv]]. — *end note*]
|
| 227 |
|
| 228 |
### Function specifiers <a id="dcl.fct.spec">[[dcl.fct.spec]]</a>
|
| 229 |
|
| 230 |
-
A *function-specifier* can be used only in a function declaration.
|
|
|
|
|
|
|
| 231 |
|
| 232 |
``` bnf
|
| 233 |
function-specifier:
|
| 234 |
virtual
|
| 235 |
explicit-specifier
|
|
@@ -268,32 +270,30 @@ struct S {
|
|
| 268 |
|
| 269 |
— *end example*]
|
| 270 |
|
| 271 |
### The `typedef` specifier <a id="dcl.typedef">[[dcl.typedef]]</a>
|
| 272 |
|
| 273 |
-
Declarations containing the *decl-specifier* `typedef` declare
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
in a declaration without a *declarator*, the program is ill-formed.
|
| 282 |
|
| 283 |
``` bnf
|
| 284 |
typedef-name:
|
| 285 |
identifier
|
| 286 |
simple-template-id
|
| 287 |
```
|
| 288 |
|
| 289 |
-
A name declared with the `typedef` specifier becomes a *typedef-name*.
|
| 290 |
-
|
| 291 |
-
[[dcl.decl]] or *simple-template-id* [[temp.pre]]
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
[[dcl.enum]] does.
|
| 295 |
|
| 296 |
[*Example 1*:
|
| 297 |
|
| 298 |
After
|
| 299 |
|
|
@@ -311,16 +311,16 @@ extern KLICKSP metricp;
|
|
| 311 |
are all correct declarations; the type of `distance` is `int` and that
|
| 312 |
of `metricp` is “pointer to `int`”.
|
| 313 |
|
| 314 |
— *end example*]
|
| 315 |
|
| 316 |
-
A
|
| 317 |
*identifier* following the `using` keyword is not looked up; it becomes
|
| 318 |
-
|
| 319 |
-
the *identifier* appertains to that
|
| 320 |
-
|
| 321 |
-
`typedef` specifier.
|
| 322 |
|
| 323 |
[*Example 2*:
|
| 324 |
|
| 325 |
``` cpp
|
| 326 |
using handler_t = void (*)(int);
|
|
@@ -335,11 +335,11 @@ using cell = P<cell*>; // error: cell not found[basic.scope.pdecl]
|
|
| 335 |
The *defining-type-specifier-seq* of the *defining-type-id* shall not
|
| 336 |
define a class or enumeration if the *alias-declaration* is the
|
| 337 |
*declaration* of a *template-declaration*.
|
| 338 |
|
| 339 |
A *simple-template-id* is only a *typedef-name* if its *template-name*
|
| 340 |
-
names an alias template or a template
|
| 341 |
|
| 342 |
[*Note 1*: A *simple-template-id* that names a class template
|
| 343 |
specialization is a *class-name* [[class.name]]. If a *typedef-name* is
|
| 344 |
used to identify the subject of an *elaborated-type-specifier*
|
| 345 |
[[dcl.type.elab]], a class definition [[class]], a constructor
|
|
@@ -405,14 +405,15 @@ The `friend` specifier is used to specify access to class members; see
|
|
| 405 |
[[class.friend]].
|
| 406 |
|
| 407 |
### The `constexpr` and `consteval` specifiers <a id="dcl.constexpr">[[dcl.constexpr]]</a>
|
| 408 |
|
| 409 |
The `constexpr` specifier shall be applied only to the definition of a
|
| 410 |
-
variable or variable template
|
| 411 |
-
function template. The `consteval`
|
| 412 |
-
|
| 413 |
-
|
|
|
|
| 414 |
implicitly an inline function or variable [[dcl.inline]]. If any
|
| 415 |
declaration of a function or function template has a `constexpr` or
|
| 416 |
`consteval` specifier, then all its declarations shall contain the same
|
| 417 |
specifier.
|
| 418 |
|
|
@@ -452,21 +453,18 @@ extern constexpr int memsz; // error: not a definition
|
|
| 452 |
— *end example*]
|
| 453 |
|
| 454 |
A `constexpr` or `consteval` specifier used in the declaration of a
|
| 455 |
function declares that function to be a *constexpr function*.
|
| 456 |
|
| 457 |
-
[*Note 3*: A function
|
| 458 |
-
|
| 459 |
|
| 460 |
A destructor, an allocation function, or a deallocation function shall
|
| 461 |
not be declared with the `consteval` specifier.
|
| 462 |
|
| 463 |
-
A function is *constexpr-suitable* if
|
| 464 |
-
|
| 465 |
-
- it is not a coroutine [[dcl.fct.def.coroutine]], and
|
| 466 |
-
- if the function is a constructor or destructor, its class does not
|
| 467 |
-
have any virtual base classes.
|
| 468 |
|
| 469 |
Except for instantiated constexpr functions, non-templated constexpr
|
| 470 |
functions shall be constexpr-suitable.
|
| 471 |
|
| 472 |
[*Example 2*:
|
|
@@ -536,12 +534,11 @@ int bar(int x, int y) // error: redefinition of bar
|
|
| 536 |
|
| 537 |
— *end example*]
|
| 538 |
|
| 539 |
A `constexpr` specifier used in an object declaration declares the
|
| 540 |
object as const. Such an object shall have literal type and shall be
|
| 541 |
-
initialized.
|
| 542 |
-
full-expression of the initialization shall be a constant expression
|
| 543 |
[[expr.const]]. A `constexpr` variable that is an object, as well as any
|
| 544 |
temporary to which a `constexpr` reference is bound, shall have constant
|
| 545 |
destruction.
|
| 546 |
|
| 547 |
[*Example 4*:
|
|
@@ -550,28 +547,44 @@ destruction.
|
|
| 550 |
struct pixel {
|
| 551 |
int x, y;
|
| 552 |
};
|
| 553 |
constexpr pixel ur = { 1294, 1024 }; // OK
|
| 554 |
constexpr pixel origin; // error: initializer missing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 555 |
```
|
| 556 |
|
| 557 |
— *end example*]
|
| 558 |
|
| 559 |
### The `constinit` specifier <a id="dcl.constinit">[[dcl.constinit]]</a>
|
| 560 |
|
| 561 |
The `constinit` specifier shall be applied only to a declaration of a
|
| 562 |
-
variable with static or thread storage duration
|
| 563 |
-
|
| 564 |
-
|
| 565 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 566 |
|
| 567 |
If a variable declared with the `constinit` specifier has dynamic
|
| 568 |
initialization [[basic.start.dynamic]], the program is ill-formed, even
|
| 569 |
if the implementation would perform that initialization as a static
|
| 570 |
initialization [[basic.start.static]].
|
| 571 |
|
| 572 |
-
[*Note
|
| 573 |
initialized during static initialization. — *end note*]
|
| 574 |
|
| 575 |
[*Example 1*:
|
| 576 |
|
| 577 |
``` cpp
|
|
@@ -584,50 +597,49 @@ constinit const char * d = f(false); // error
|
|
| 584 |
— *end example*]
|
| 585 |
|
| 586 |
### The `inline` specifier <a id="dcl.inline">[[dcl.inline]]</a>
|
| 587 |
|
| 588 |
The `inline` specifier shall be applied only to the declaration of a
|
| 589 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 590 |
|
| 591 |
A function declaration [[dcl.fct]], [[class.mfct]], [[class.friend]]
|
| 592 |
-
with an `inline` specifier declares an *inline function*.
|
| 593 |
-
|
| 594 |
-
the function body at the point of call is to be preferred to the usual
|
| 595 |
-
function call mechanism. An implementation is not required to perform
|
| 596 |
-
this inline substitution at the point of call; however, even if this
|
| 597 |
-
inline substitution is omitted, the other rules for inline functions
|
| 598 |
-
specified in this subclause shall still be respected.
|
| 599 |
|
| 600 |
-
[*Note 1*:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
function. In certain cases, an inline function cannot use names with
|
| 602 |
internal linkage; see [[basic.link]]. — *end note*]
|
| 603 |
|
| 604 |
-
|
| 605 |
-
|
| 606 |
-
|
| 607 |
-
|
| 608 |
-
|
| 609 |
-
|
| 610 |
-
|
| 611 |
|
| 612 |
If a definition of a function or variable is reachable at the point of
|
| 613 |
its first declaration as inline, the program is ill-formed. If a
|
| 614 |
function or variable with external or module linkage is declared inline
|
| 615 |
in one definition domain, an inline declaration of it shall be reachable
|
| 616 |
from the end of every definition domain in which it is declared; no
|
| 617 |
diagnostic is required.
|
| 618 |
|
| 619 |
-
[*Note
|
| 620 |
can be encountered before its definition becomes reachable in a
|
| 621 |
translation unit. — *end note*]
|
| 622 |
|
| 623 |
-
[*Note 3*: An inline function or variable with external or module
|
| 624 |
-
linkage can be defined in multiple translation units [[basic.def.odr]],
|
| 625 |
-
but is one entity with one address. A type or `static` variable defined
|
| 626 |
-
in the body of such a function is therefore a single
|
| 627 |
-
entity. — *end note*]
|
| 628 |
-
|
| 629 |
If an inline function or variable that is attached to a named module is
|
| 630 |
declared in a definition domain, it shall be defined in that domain.
|
| 631 |
|
| 632 |
[*Note 4*: A constexpr function [[dcl.constexpr]] is implicitly inline.
|
| 633 |
In the global module, a function defined within a class definition is
|
|
@@ -727,11 +739,11 @@ some other access path.
|
|
| 727 |
|
| 728 |
[*Note 4*: Cv-qualifiers are supported by the type system so that they
|
| 729 |
cannot be subverted without casting [[expr.const.cast]]. — *end note*]
|
| 730 |
|
| 731 |
Any attempt to modify
|
| 732 |
-
[[expr.
|
| 733 |
[[basic.type.qualifier]] during its lifetime [[basic.life]] results in
|
| 734 |
undefined behavior.
|
| 735 |
|
| 736 |
[*Example 1*:
|
| 737 |
|
|
@@ -779,27 +791,27 @@ The semantics of an access through a volatile glvalue are
|
|
| 779 |
*implementation-defined*. If an attempt is made to access an object
|
| 780 |
defined with a volatile-qualified type through the use of a non-volatile
|
| 781 |
glvalue, the behavior is undefined.
|
| 782 |
|
| 783 |
[*Note 5*: `volatile` is a hint to the implementation to avoid
|
| 784 |
-
aggressive optimization involving the object because
|
| 785 |
-
|
| 786 |
-
Furthermore, for some implementations, `volatile`
|
| 787 |
-
special hardware instructions are
|
| 788 |
-
[[intro.execution]] for detailed semantics. In general, the
|
| 789 |
-
`volatile` are intended to be the same in C++ as they are
|
| 790 |
-
C. — *end note*]
|
| 791 |
|
| 792 |
#### Simple type specifiers <a id="dcl.type.simple">[[dcl.type.simple]]</a>
|
| 793 |
|
| 794 |
The simple type specifiers are
|
| 795 |
|
| 796 |
``` bnf
|
| 797 |
simple-type-specifier:
|
| 798 |
nested-name-specifierₒₚₜ type-name
|
| 799 |
nested-name-specifier template simple-template-id
|
| 800 |
-
|
| 801 |
placeholder-type-specifier
|
| 802 |
nested-name-specifierₒₚₜ template-name
|
| 803 |
char
|
| 804 |
char8_t
|
| 805 |
char16_t
|
|
@@ -821,24 +833,36 @@ type-name:
|
|
| 821 |
class-name
|
| 822 |
enum-name
|
| 823 |
typedef-name
|
| 824 |
```
|
| 825 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 826 |
The component names of a *simple-type-specifier* are those of its
|
| 827 |
*nested-name-specifier*, *type-name*, *simple-template-id*,
|
| 828 |
*template-name*, and/or *type-constraint* (if it is a
|
| 829 |
*placeholder-type-specifier*). The component name of a *type-name* is
|
| 830 |
the first name in it.
|
| 831 |
|
| 832 |
A *placeholder-type-specifier* is a placeholder for a type to be deduced
|
| 833 |
-
[[dcl.spec.auto]]. A *type-specifier*
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
*nested-name-specifier*
|
| 837 |
-
*template-name*
|
| 838 |
-
|
| 839 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 840 |
|
| 841 |
``` bnf
|
| 842 |
typenameₒₚₜ nested-name-specifierₒₚₜ templateₒₚₜ simple-template-id
|
| 843 |
```
|
| 844 |
|
|
@@ -859,12 +883,14 @@ combinations of *simple-type-specifier*s and the types they specify.
|
|
| 859 |
| Specifier(s) | Type |
|
| 860 |
| ---------------------------- | ------------------------------------------------- |
|
| 861 |
| *type-name* | the type named |
|
| 862 |
| *simple-template-id* | the type as defined in~ [[temp.names]] |
|
| 863 |
| *decltype-specifier* | the type as defined in~ [[dcl.type.decltype]] |
|
|
|
|
| 864 |
| *placeholder-type-specifier* | the type as defined in~ [[dcl.spec.auto]] |
|
| 865 |
| *template-name* | the type as defined in~ [[dcl.type.class.deduct]] |
|
|
|
|
| 866 |
| `char` | ```char`'' |
|
| 867 |
| `unsigned char` | ```unsigned char`'' |
|
| 868 |
| `signed char` | ```signed char`'' |
|
| 869 |
| `char8_t` | ```char8_t`'' |
|
| 870 |
| `char16_t` | ```char16_t`'' |
|
|
@@ -906,10 +932,28 @@ intermixed with other *decl-specifier*s in any order.
|
|
| 906 |
[*Note 2*: It is *implementation-defined* whether objects of `char`
|
| 907 |
type are represented as signed or unsigned quantities. The `signed`
|
| 908 |
specifier forces `char` objects to be signed; it is redundant in other
|
| 909 |
contexts. — *end note*]
|
| 910 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 911 |
#### Elaborated type specifiers <a id="dcl.type.elab">[[dcl.type.elab]]</a>
|
| 912 |
|
| 913 |
``` bnf
|
| 914 |
elaborated-type-specifier:
|
| 915 |
class-key attribute-specifier-seqₒₚₜ nested-name-specifierₒₚₜ identifier
|
|
@@ -922,77 +966,77 @@ The component names of an *elaborated-type-specifier* are its
|
|
| 922 |
*identifier* (if any) and those of its *nested-name-specifier* and
|
| 923 |
*simple-template-id* (if any).
|
| 924 |
|
| 925 |
If an *elaborated-type-specifier* is the sole constituent of a
|
| 926 |
declaration, the declaration is ill-formed unless it is an explicit
|
| 927 |
-
specialization [[temp.expl.spec]],
|
| 928 |
-
[[temp.
|
|
|
|
| 929 |
|
| 930 |
``` bnf
|
| 931 |
class-key attribute-specifier-seqₒₚₜ identifier ';'
|
| 932 |
class-key attribute-specifier-seqₒₚₜ simple-template-id ';'
|
| 933 |
```
|
| 934 |
|
| 935 |
In the first case, the *elaborated-type-specifier* declares the
|
| 936 |
*identifier* as a *class-name*. The second case shall appear only in an
|
| 937 |
*explicit-specialization* [[temp.expl.spec]] or in a
|
| 938 |
-
*template-declaration* (where it declares a partial specialization
|
| 939 |
-
|
| 940 |
-
|
| 941 |
|
| 942 |
Otherwise, an *elaborated-type-specifier* E shall not have an
|
| 943 |
*attribute-specifier-seq*. If E contains an *identifier* but no
|
| 944 |
*nested-name-specifier* and (unqualified) lookup for the *identifier*
|
| 945 |
finds nothing, E shall not be introduced by the `enum` keyword and
|
| 946 |
declares the *identifier* as a *class-name*. The target scope of E is
|
| 947 |
the nearest enclosing namespace or block scope.
|
| 948 |
|
| 949 |
-
|
| 950 |
-
|
| 951 |
-
of the following forms:
|
| 952 |
|
| 953 |
``` bnf
|
| 954 |
-
|
| 955 |
-
|
| 956 |
-
|
| 957 |
```
|
| 958 |
|
| 959 |
Any unqualified lookup for the *identifier* (in the first case) does not
|
| 960 |
-
consider scopes that contain the
|
|
|
|
| 961 |
|
| 962 |
[*Note 1*: A *using-directive* in the target scope is ignored if it
|
| 963 |
-
refers to a namespace not contained by that scope.
|
| 964 |
-
describes how name lookup proceeds in an
|
| 965 |
-
*elaborated-type-specifier*. — *end note*]
|
| 966 |
|
| 967 |
-
[*Note 2*:
|
| 968 |
-
|
| 969 |
-
|
|
|
|
| 970 |
|
| 971 |
-
If the *identifier* or *simple-template-id*
|
| 972 |
-
|
| 973 |
-
|
| 974 |
-
*type-
|
| 975 |
-
|
| 976 |
-
[[dcl.typedef]], [[temp.names]], the
|
| 977 |
-
ill-formed.
|
| 978 |
|
| 979 |
[*Note 3*:
|
| 980 |
|
| 981 |
This implies that, within a class template with a template
|
| 982 |
*type-parameter* `T`, the declaration
|
| 983 |
|
| 984 |
``` cpp
|
| 985 |
friend class T;
|
| 986 |
```
|
| 987 |
|
| 988 |
-
is ill-formed. However, the similar declaration `friend T;` is
|
| 989 |
-
[[class.friend]].
|
| 990 |
|
| 991 |
— *end note*]
|
| 992 |
|
| 993 |
-
The *class-key* or `enum` keyword present in
|
| 994 |
*elaborated-type-specifier* shall agree in kind with the declaration to
|
| 995 |
which the name in the *elaborated-type-specifier* refers. This rule also
|
| 996 |
applies to the form of *elaborated-type-specifier* that declares a
|
| 997 |
*class-name* or friend class since it can be construed as referring to
|
| 998 |
the definition of the class. Thus, in any *elaborated-type-specifier*,
|
|
@@ -1024,17 +1068,20 @@ follows:
|
|
| 1024 |
|
| 1025 |
- if E is an unparenthesized *id-expression* naming a structured binding
|
| 1026 |
[[dcl.struct.bind]], `decltype(E)` is the referenced type as given in
|
| 1027 |
the specification of the structured binding declaration;
|
| 1028 |
- otherwise, if E is an unparenthesized *id-expression* naming a
|
| 1029 |
-
|
| 1030 |
-
|
| 1031 |
deduction [[dcl.spec.auto]], [[dcl.type.class.deduct]];
|
| 1032 |
- otherwise, if E is an unparenthesized *id-expression* or an
|
| 1033 |
unparenthesized class member access [[expr.ref]], `decltype(E)` is the
|
| 1034 |
type of the entity named by E. If there is no such entity, the program
|
| 1035 |
is ill-formed;
|
|
|
|
|
|
|
|
|
|
| 1036 |
- otherwise, if E is an xvalue, `decltype(E)` is `T&&`, where `T` is the
|
| 1037 |
type of E;
|
| 1038 |
- otherwise, if E is an lvalue, `decltype(E)` is `T&`, where `T` is the
|
| 1039 |
type of E;
|
| 1040 |
- otherwise, `decltype(E)` is the type of E.
|
|
@@ -1051,10 +1098,19 @@ struct A { double x; };
|
|
| 1051 |
const A* a = new A();
|
| 1052 |
decltype(foo()) x1 = 17; // type is const int&&
|
| 1053 |
decltype(i) x2; // type is int
|
| 1054 |
decltype(a->x) x3; // type is double
|
| 1055 |
decltype((a->x)) x4 = x3; // type is const double&
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1056 |
```
|
| 1057 |
|
| 1058 |
— *end example*]
|
| 1059 |
|
| 1060 |
[*Note 1*: The rules for determining types involving `decltype(auto)`
|
|
@@ -1120,64 +1176,76 @@ placeholder-type-specifier:
|
|
| 1120 |
type-constraintₒₚₜ auto
|
| 1121 |
type-constraintₒₚₜ decltype '(' auto ')'
|
| 1122 |
```
|
| 1123 |
|
| 1124 |
A *placeholder-type-specifier* designates a placeholder type that will
|
| 1125 |
-
be replaced later by deduction from an initializer.
|
| 1126 |
|
| 1127 |
-
|
| 1128 |
-
|
| 1129 |
-
|
| 1130 |
-
|
| 1131 |
-
|
| 1132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1133 |
|
| 1134 |
[*Note 1*: Having a generic parameter type placeholder signifies that
|
| 1135 |
the function is an abbreviated function template [[dcl.fct]] or the
|
| 1136 |
lambda is a generic lambda [[expr.prim.lambda]]. — *end note*]
|
| 1137 |
|
| 1138 |
-
A placeholder type can appear
|
| 1139 |
-
|
| 1140 |
-
|
| 1141 |
-
|
| 1142 |
-
|
| 1143 |
-
|
| 1144 |
-
|
| 1145 |
-
|
| 1146 |
-
non-discarded `return` statements, if any, in the body of the function
|
| 1147 |
-
[[stmt.if]].
|
| 1148 |
|
| 1149 |
The type of a variable declared using a placeholder type is deduced from
|
| 1150 |
its initializer. This use is allowed in an initializing declaration
|
| 1151 |
[[dcl.init]] of a variable. The placeholder type shall appear as one of
|
| 1152 |
-
the *decl-specifier*s in the *decl-specifier-seq*
|
| 1153 |
-
*
|
| 1154 |
-
|
|
|
|
|
|
|
| 1155 |
|
| 1156 |
[*Example 1*:
|
| 1157 |
|
| 1158 |
``` cpp
|
| 1159 |
auto x = 5; // OK, x has type int
|
| 1160 |
const auto *v = &x, u = 6; // OK, v has type const int*, u has type const int
|
| 1161 |
static auto y = 0.0; // OK, y has type double
|
| 1162 |
auto int r; // error: auto is not a storage-class-specifier
|
| 1163 |
auto f() -> int; // OK, f returns int
|
| 1164 |
auto g() { return 0.0; } // OK, g returns double
|
|
|
|
| 1165 |
auto h(); // OK, h's return type will be deduced when it is defined
|
| 1166 |
```
|
| 1167 |
|
| 1168 |
— *end example*]
|
| 1169 |
|
| 1170 |
The `auto` *type-specifier* can also be used to introduce a structured
|
| 1171 |
binding declaration [[dcl.struct.bind]].
|
| 1172 |
|
| 1173 |
-
A placeholder type can also be used in the *type-specifier-seq*
|
| 1174 |
-
*new-type-id* or *type-id* of a *new-expression* [[expr.new]]
|
| 1175 |
-
*
|
| 1176 |
-
|
| 1177 |
-
|
| 1178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1179 |
|
| 1180 |
A program that uses a placeholder type in a context not explicitly
|
| 1181 |
allowed in [[dcl.spec.auto]] is ill-formed.
|
| 1182 |
|
| 1183 |
If the *init-declarator-list* contains more than one *init-declarator*,
|
|
@@ -1241,10 +1309,25 @@ auto sum(int i) {
|
|
| 1241 |
}
|
| 1242 |
```
|
| 1243 |
|
| 1244 |
— *end example*]
|
| 1245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1246 |
Return type deduction for a templated function with a placeholder in its
|
| 1247 |
declared type occurs when the definition is instantiated even if the
|
| 1248 |
function body contains a `return` statement with a non-type-dependent
|
| 1249 |
operand.
|
| 1250 |
|
|
@@ -1252,11 +1335,11 @@ operand.
|
|
| 1252 |
template will cause an implicit instantiation. Any errors that arise
|
| 1253 |
from this instantiation are not in the immediate context of the function
|
| 1254 |
type and can result in the program being ill-formed
|
| 1255 |
[[temp.deduct]]. — *end note*]
|
| 1256 |
|
| 1257 |
-
[*Example
|
| 1258 |
|
| 1259 |
``` cpp
|
| 1260 |
template <class T> auto f(T t) { return t; } // return type deduced at instantiation time
|
| 1261 |
typedef decltype(f(1)) fint_t; // instantiates f<int> to deduce return type
|
| 1262 |
template<class T> auto f(T* t) { return *t; }
|
|
@@ -1269,11 +1352,11 @@ void g() { int (*p)(int*) = &f; } // instantiates both fs to deter
|
|
| 1269 |
If a function or function template F has a declared return type that
|
| 1270 |
uses a placeholder type, redeclarations or specializations of F shall
|
| 1271 |
use that placeholder type, not a deduced type; otherwise, they shall not
|
| 1272 |
use a placeholder type.
|
| 1273 |
|
| 1274 |
-
[*Example
|
| 1275 |
|
| 1276 |
``` cpp
|
| 1277 |
auto f();
|
| 1278 |
auto f() { return 42; } // return type is int
|
| 1279 |
auto f(); // OK
|
|
@@ -1314,11 +1397,11 @@ shall not be a coroutine [[dcl.fct.def.coroutine]].
|
|
| 1314 |
An explicit instantiation declaration [[temp.explicit]] does not cause
|
| 1315 |
the instantiation of an entity declared using a placeholder type, but it
|
| 1316 |
also does not prevent that entity from being instantiated as needed to
|
| 1317 |
determine its type.
|
| 1318 |
|
| 1319 |
-
[*Example
|
| 1320 |
|
| 1321 |
``` cpp
|
| 1322 |
template <typename T> auto f(T t) { return t; }
|
| 1323 |
extern template auto f(int); // does not instantiate f<int>
|
| 1324 |
int (*p)(int) = f; // instantiates f<int> to determine its return type, but an explicit
|
|
@@ -1364,32 +1447,31 @@ A type `T` containing a placeholder type, and a corresponding
|
|
| 1364 |
single brace-enclosed *assignment-expression* and E is the
|
| 1365 |
*assignment-expression*.
|
| 1366 |
- If the initializer is a parenthesized *expression-list*, the
|
| 1367 |
*expression-list* shall be a single *assignment-expression* and E is
|
| 1368 |
the *assignment-expression*.
|
| 1369 |
-
- For a
|
| 1370 |
-
placeholder type, `T` is the declared type of the
|
| 1371 |
parameter and E is the corresponding template argument.
|
| 1372 |
|
| 1373 |
`T` shall not be an array type.
|
| 1374 |
|
| 1375 |
If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
|
| 1376 |
`auto`, the deduced type T' replacing `T` is determined using the rules
|
| 1377 |
for template argument deduction. If the initialization is
|
| 1378 |
copy-list-initialization, a declaration of `std::initializer_list` shall
|
| 1379 |
precede [[basic.lookup.general]] the *placeholder-type-specifier*.
|
| 1380 |
-
Obtain `P` from `T` by replacing the
|
| 1381 |
-
|
| 1382 |
-
|
| 1383 |
-
|
| 1384 |
-
|
| 1385 |
-
|
| 1386 |
-
|
| 1387 |
-
|
| 1388 |
-
deduced `U` into `P`.
|
| 1389 |
|
| 1390 |
-
[*Example
|
| 1391 |
|
| 1392 |
``` cpp
|
| 1393 |
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
|
| 1394 |
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
|
| 1395 |
auto x3{ 1, 2 }; // error: not a single element
|
|
@@ -1397,11 +1479,11 @@ auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
|
|
| 1397 |
auto x5{ 3 }; // decltype(x5) is int
|
| 1398 |
```
|
| 1399 |
|
| 1400 |
— *end example*]
|
| 1401 |
|
| 1402 |
-
[*Example
|
| 1403 |
|
| 1404 |
``` cpp
|
| 1405 |
const auto &i = expr;
|
| 1406 |
```
|
| 1407 |
|
|
@@ -1417,11 +1499,11 @@ template <class U> void f(const U& u);
|
|
| 1417 |
If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
|
| 1418 |
`decltype(auto)`, `T` shall be the placeholder alone. The type deduced
|
| 1419 |
for `T` is determined as described in [[dcl.type.decltype]], as though
|
| 1420 |
E had been the operand of the `decltype`.
|
| 1421 |
|
| 1422 |
-
[*Example
|
| 1423 |
|
| 1424 |
``` cpp
|
| 1425 |
int i;
|
| 1426 |
int&& f();
|
| 1427 |
auto x2a(i); // decltype(x2a) is int
|
|
@@ -1496,5 +1578,51 @@ auto d = container(v.begin(), v.end()); // OK, deduces double for T
|
|
| 1496 |
container e{5, 6}; // error: int is not an iterator
|
| 1497 |
```
|
| 1498 |
|
| 1499 |
— *end example*]
|
| 1500 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
appertains to the type determined by the preceding *decl-specifier*s
|
| 28 |
[[dcl.meaning]]. The *attribute-specifier-seq* affects the type only for
|
| 29 |
the declaration it appears in, not other declarations involving the same
|
| 30 |
type.
|
| 31 |
|
| 32 |
+
At most one of each of the *decl-specifier*s `friend`, `typedef`, or
|
| 33 |
+
`inline` shall appear in a *decl-specifier-seq*. At most one of the
|
| 34 |
+
`constexpr`, `consteval`, and `constinit` keywords shall appear in a
|
| 35 |
+
*decl-specifier-seq*.
|
| 36 |
|
| 37 |
If a *type-name* is encountered while parsing a *decl-specifier-seq*, it
|
| 38 |
is interpreted as part of the *decl-specifier-seq* if and only if there
|
| 39 |
is no previous *defining-type-specifier* other than a *cv-qualifier* in
|
| 40 |
the *decl-specifier-seq*. The sequence shall be self-consistent as
|
|
|
|
| 225 |
object is const
|
| 226 |
[[basic.type.qualifier]], [[dcl.type.cv]]. — *end note*]
|
| 227 |
|
| 228 |
### Function specifiers <a id="dcl.fct.spec">[[dcl.fct.spec]]</a>
|
| 229 |
|
| 230 |
+
A *function-specifier* can be used only in a function declaration. At
|
| 231 |
+
most one *explicit-specifier* and at most one `virtual` keyword shall
|
| 232 |
+
appear in a *decl-specifier-seq*.
|
| 233 |
|
| 234 |
``` bnf
|
| 235 |
function-specifier:
|
| 236 |
virtual
|
| 237 |
explicit-specifier
|
|
|
|
| 270 |
|
| 271 |
— *end example*]
|
| 272 |
|
| 273 |
### The `typedef` specifier <a id="dcl.typedef">[[dcl.typedef]]</a>
|
| 274 |
|
| 275 |
+
Declarations containing the *decl-specifier* `typedef` declare *type
|
| 276 |
+
aliases*. The `typedef` specifier shall not be combined in a
|
| 277 |
+
*decl-specifier-seq* with any other kind of specifier except a
|
| 278 |
+
*defining-type-specifier*, and it shall not be used in the
|
| 279 |
+
*decl-specifier-seq* of a *parameter-declaration* [[dcl.fct]] nor in the
|
| 280 |
+
*decl-specifier-seq* of a *function-definition* [[dcl.fct.def]]. If a
|
| 281 |
+
`typedef` specifier appears in a declaration without a *declarator*, the
|
| 282 |
+
program is ill-formed.
|
|
|
|
| 283 |
|
| 284 |
``` bnf
|
| 285 |
typedef-name:
|
| 286 |
identifier
|
| 287 |
simple-template-id
|
| 288 |
```
|
| 289 |
|
| 290 |
+
A name declared with the `typedef` specifier becomes a *typedef-name*.
|
| 291 |
+
The underlying entity of the type alias is the type associated with the
|
| 292 |
+
*identifier* [[dcl.decl]] or *simple-template-id* [[temp.pre]]. A
|
| 293 |
+
*typedef-name* does not introduce a new type the way a class declaration
|
| 294 |
+
[[class.name]] or enum declaration [[dcl.enum]] does.
|
|
|
|
| 295 |
|
| 296 |
[*Example 1*:
|
| 297 |
|
| 298 |
After
|
| 299 |
|
|
|
|
| 311 |
are all correct declarations; the type of `distance` is `int` and that
|
| 312 |
of `metricp` is “pointer to `int`”.
|
| 313 |
|
| 314 |
— *end example*]
|
| 315 |
|
| 316 |
+
A type alias can also be declared by an *alias-declaration*. The
|
| 317 |
*identifier* following the `using` keyword is not looked up; it becomes
|
| 318 |
+
the *typedef-name* of a type alias and the optional
|
| 319 |
+
*attribute-specifier-seq* following the *identifier* appertains to that
|
| 320 |
+
type alias. Such a type alias has the same semantics as if it were
|
| 321 |
+
introduced by the `typedef` specifier.
|
| 322 |
|
| 323 |
[*Example 2*:
|
| 324 |
|
| 325 |
``` cpp
|
| 326 |
using handler_t = void (*)(int);
|
|
|
|
| 335 |
The *defining-type-specifier-seq* of the *defining-type-id* shall not
|
| 336 |
define a class or enumeration if the *alias-declaration* is the
|
| 337 |
*declaration* of a *template-declaration*.
|
| 338 |
|
| 339 |
A *simple-template-id* is only a *typedef-name* if its *template-name*
|
| 340 |
+
names an alias template or a type template template parameter.
|
| 341 |
|
| 342 |
[*Note 1*: A *simple-template-id* that names a class template
|
| 343 |
specialization is a *class-name* [[class.name]]. If a *typedef-name* is
|
| 344 |
used to identify the subject of an *elaborated-type-specifier*
|
| 345 |
[[dcl.type.elab]], a class definition [[class]], a constructor
|
|
|
|
| 405 |
[[class.friend]].
|
| 406 |
|
| 407 |
### The `constexpr` and `consteval` specifiers <a id="dcl.constexpr">[[dcl.constexpr]]</a>
|
| 408 |
|
| 409 |
The `constexpr` specifier shall be applied only to the definition of a
|
| 410 |
+
variable or variable template, a structured binding declaration, or the
|
| 411 |
+
declaration of a function or function template. The `consteval`
|
| 412 |
+
specifier shall be applied only to the declaration of a function or
|
| 413 |
+
function template. A function or static data member declared with the
|
| 414 |
+
`constexpr` or `consteval` specifier on its first declaration is
|
| 415 |
implicitly an inline function or variable [[dcl.inline]]. If any
|
| 416 |
declaration of a function or function template has a `constexpr` or
|
| 417 |
`consteval` specifier, then all its declarations shall contain the same
|
| 418 |
specifier.
|
| 419 |
|
|
|
|
| 453 |
— *end example*]
|
| 454 |
|
| 455 |
A `constexpr` or `consteval` specifier used in the declaration of a
|
| 456 |
function declares that function to be a *constexpr function*.
|
| 457 |
|
| 458 |
+
[*Note 3*: A function declared with the `consteval` specifier is an
|
| 459 |
+
immediate function [[expr.const]]. — *end note*]
|
| 460 |
|
| 461 |
A destructor, an allocation function, or a deallocation function shall
|
| 462 |
not be declared with the `consteval` specifier.
|
| 463 |
|
| 464 |
+
A function is *constexpr-suitable* if it is not a coroutine
|
| 465 |
+
[[dcl.fct.def.coroutine]].
|
|
|
|
|
|
|
|
|
|
| 466 |
|
| 467 |
Except for instantiated constexpr functions, non-templated constexpr
|
| 468 |
functions shall be constexpr-suitable.
|
| 469 |
|
| 470 |
[*Example 2*:
|
|
|
|
| 534 |
|
| 535 |
— *end example*]
|
| 536 |
|
| 537 |
A `constexpr` specifier used in an object declaration declares the
|
| 538 |
object as const. Such an object shall have literal type and shall be
|
| 539 |
+
initialized. A `constexpr` variable shall be constant-initializable
|
|
|
|
| 540 |
[[expr.const]]. A `constexpr` variable that is an object, as well as any
|
| 541 |
temporary to which a `constexpr` reference is bound, shall have constant
|
| 542 |
destruction.
|
| 543 |
|
| 544 |
[*Example 4*:
|
|
|
|
| 547 |
struct pixel {
|
| 548 |
int x, y;
|
| 549 |
};
|
| 550 |
constexpr pixel ur = { 1294, 1024 }; // OK
|
| 551 |
constexpr pixel origin; // error: initializer missing
|
| 552 |
+
|
| 553 |
+
namespace N {
|
| 554 |
+
void f() {
|
| 555 |
+
int x;
|
| 556 |
+
constexpr int& ar = x; // OK
|
| 557 |
+
static constexpr int& sr = x; // error: x is not constexpr-representable
|
| 558 |
+
// at the point indicated below
|
| 559 |
+
}
|
| 560 |
+
// immediate scope here is that of N
|
| 561 |
+
}
|
| 562 |
```
|
| 563 |
|
| 564 |
— *end example*]
|
| 565 |
|
| 566 |
### The `constinit` specifier <a id="dcl.constinit">[[dcl.constinit]]</a>
|
| 567 |
|
| 568 |
The `constinit` specifier shall be applied only to a declaration of a
|
| 569 |
+
variable with static or thread storage duration or to a structured
|
| 570 |
+
binding declaration [[dcl.struct.bind]].
|
| 571 |
+
|
| 572 |
+
[*Note 1*: A structured binding declaration introduces a uniquely named
|
| 573 |
+
variable, to which the `constinit` specifier applies. — *end note*]
|
| 574 |
+
|
| 575 |
+
If the specifier is applied to any declaration of a variable, it shall
|
| 576 |
+
be applied to the initializing declaration. No diagnostic is required if
|
| 577 |
+
no `constinit` declaration is reachable at the point of the initializing
|
| 578 |
+
declaration.
|
| 579 |
|
| 580 |
If a variable declared with the `constinit` specifier has dynamic
|
| 581 |
initialization [[basic.start.dynamic]], the program is ill-formed, even
|
| 582 |
if the implementation would perform that initialization as a static
|
| 583 |
initialization [[basic.start.static]].
|
| 584 |
|
| 585 |
+
[*Note 2*: The `constinit` specifier ensures that the variable is
|
| 586 |
initialized during static initialization. — *end note*]
|
| 587 |
|
| 588 |
[*Example 1*:
|
| 589 |
|
| 590 |
``` cpp
|
|
|
|
| 597 |
— *end example*]
|
| 598 |
|
| 599 |
### The `inline` specifier <a id="dcl.inline">[[dcl.inline]]</a>
|
| 600 |
|
| 601 |
The `inline` specifier shall be applied only to the declaration of a
|
| 602 |
+
function or variable. The `inline` specifier shall not appear on a block
|
| 603 |
+
scope declaration or on the declaration of a function parameter. If the
|
| 604 |
+
`inline` specifier is used in a friend function declaration, that
|
| 605 |
+
declaration shall be a definition or the function shall have previously
|
| 606 |
+
been declared inline.
|
| 607 |
|
| 608 |
A function declaration [[dcl.fct]], [[class.mfct]], [[class.friend]]
|
| 609 |
+
with an `inline` specifier declares an *inline function*. A variable
|
| 610 |
+
declaration with an `inline` specifier declares an *inline variable*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 611 |
|
| 612 |
+
[*Note 1*: An inline function or variable with external or module
|
| 613 |
+
linkage can be defined in multiple translation units [[basic.def.odr]],
|
| 614 |
+
but is one entity with one address. A type or `static` variable defined
|
| 615 |
+
in the body of such a function is therefore a single
|
| 616 |
+
entity. — *end note*]
|
| 617 |
+
|
| 618 |
+
[*Note 2*: The `inline` keyword has no effect on the linkage of a
|
| 619 |
function. In certain cases, an inline function cannot use names with
|
| 620 |
internal linkage; see [[basic.link]]. — *end note*]
|
| 621 |
|
| 622 |
+
The inline specifier indicates to the implementation that inline
|
| 623 |
+
substitution of the function body at the point of call is to be
|
| 624 |
+
preferred to the usual function call mechanism. An implementation is not
|
| 625 |
+
required to perform this inline substitution at the point of call;
|
| 626 |
+
however, even if this inline substitution is omitted, the other rules
|
| 627 |
+
for inline functions specified in this subclause shall still be
|
| 628 |
+
respected.
|
| 629 |
|
| 630 |
If a definition of a function or variable is reachable at the point of
|
| 631 |
its first declaration as inline, the program is ill-formed. If a
|
| 632 |
function or variable with external or module linkage is declared inline
|
| 633 |
in one definition domain, an inline declaration of it shall be reachable
|
| 634 |
from the end of every definition domain in which it is declared; no
|
| 635 |
diagnostic is required.
|
| 636 |
|
| 637 |
+
[*Note 3*: A call to an inline function or a use of an inline variable
|
| 638 |
can be encountered before its definition becomes reachable in a
|
| 639 |
translation unit. — *end note*]
|
| 640 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 641 |
If an inline function or variable that is attached to a named module is
|
| 642 |
declared in a definition domain, it shall be defined in that domain.
|
| 643 |
|
| 644 |
[*Note 4*: A constexpr function [[dcl.constexpr]] is implicitly inline.
|
| 645 |
In the global module, a function defined within a class definition is
|
|
|
|
| 739 |
|
| 740 |
[*Note 4*: Cv-qualifiers are supported by the type system so that they
|
| 741 |
cannot be subverted without casting [[expr.const.cast]]. — *end note*]
|
| 742 |
|
| 743 |
Any attempt to modify
|
| 744 |
+
[[expr.assign]], [[expr.post.incr]], [[expr.pre.incr]] a const object
|
| 745 |
[[basic.type.qualifier]] during its lifetime [[basic.life]] results in
|
| 746 |
undefined behavior.
|
| 747 |
|
| 748 |
[*Example 1*:
|
| 749 |
|
|
|
|
| 791 |
*implementation-defined*. If an attempt is made to access an object
|
| 792 |
defined with a volatile-qualified type through the use of a non-volatile
|
| 793 |
glvalue, the behavior is undefined.
|
| 794 |
|
| 795 |
[*Note 5*: `volatile` is a hint to the implementation to avoid
|
| 796 |
+
aggressive optimization involving the object because it is possible for
|
| 797 |
+
the value of the object to change by means undetectable by an
|
| 798 |
+
implementation. Furthermore, for some implementations, `volatile` can
|
| 799 |
+
indicate that special hardware instructions are needed to access the
|
| 800 |
+
object. See [[intro.execution]] for detailed semantics. In general, the
|
| 801 |
+
semantics of `volatile` are intended to be the same in C++ as they are
|
| 802 |
+
in C. — *end note*]
|
| 803 |
|
| 804 |
#### Simple type specifiers <a id="dcl.type.simple">[[dcl.type.simple]]</a>
|
| 805 |
|
| 806 |
The simple type specifiers are
|
| 807 |
|
| 808 |
``` bnf
|
| 809 |
simple-type-specifier:
|
| 810 |
nested-name-specifierₒₚₜ type-name
|
| 811 |
nested-name-specifier template simple-template-id
|
| 812 |
+
computed-type-specifier
|
| 813 |
placeholder-type-specifier
|
| 814 |
nested-name-specifierₒₚₜ template-name
|
| 815 |
char
|
| 816 |
char8_t
|
| 817 |
char16_t
|
|
|
|
| 833 |
class-name
|
| 834 |
enum-name
|
| 835 |
typedef-name
|
| 836 |
```
|
| 837 |
|
| 838 |
+
``` bnf
|
| 839 |
+
computed-type-specifier:
|
| 840 |
+
decltype-specifier
|
| 841 |
+
pack-index-specifier
|
| 842 |
+
splice-type-specifier
|
| 843 |
+
```
|
| 844 |
+
|
| 845 |
The component names of a *simple-type-specifier* are those of its
|
| 846 |
*nested-name-specifier*, *type-name*, *simple-template-id*,
|
| 847 |
*template-name*, and/or *type-constraint* (if it is a
|
| 848 |
*placeholder-type-specifier*). The component name of a *type-name* is
|
| 849 |
the first name in it.
|
| 850 |
|
| 851 |
A *placeholder-type-specifier* is a placeholder for a type to be deduced
|
| 852 |
+
[[dcl.spec.auto]]. A *type-specifier* is a placeholder for a deduced
|
| 853 |
+
class type [[dcl.type.class.deduct]] if either
|
| 854 |
+
|
| 855 |
+
- it is of the form `typename`ₒₚₜ *nested-name-specifier*ₒₚₜ
|
| 856 |
+
*template-name* or
|
| 857 |
+
- it is of the form `typename`ₒₚₜ *splice-specifier* and the
|
| 858 |
+
*splice-specifier* designates a class template or alias template.
|
| 859 |
+
|
| 860 |
+
The *nested-name-specifier* or *splice-specifier*, if any, shall be
|
| 861 |
+
non-dependent and the *template-name* or *splice-specifier* shall
|
| 862 |
+
designate a deducible template. A *deducible template* is either a class
|
| 863 |
+
template or is an alias template whose *defining-type-id* is of the form
|
| 864 |
|
| 865 |
``` bnf
|
| 866 |
typenameₒₚₜ nested-name-specifierₒₚₜ templateₒₚₜ simple-template-id
|
| 867 |
```
|
| 868 |
|
|
|
|
| 883 |
| Specifier(s) | Type |
|
| 884 |
| ---------------------------- | ------------------------------------------------- |
|
| 885 |
| *type-name* | the type named |
|
| 886 |
| *simple-template-id* | the type as defined in~ [[temp.names]] |
|
| 887 |
| *decltype-specifier* | the type as defined in~ [[dcl.type.decltype]] |
|
| 888 |
+
| *pack-index-specifier* | the type as defined in~ [[dcl.type.pack.index]] |
|
| 889 |
| *placeholder-type-specifier* | the type as defined in~ [[dcl.spec.auto]] |
|
| 890 |
| *template-name* | the type as defined in~ [[dcl.type.class.deduct]] |
|
| 891 |
+
| *splice-type-specifier* | the type as defined in~ [[dcl.type.splice]] |
|
| 892 |
| `char` | ```char`'' |
|
| 893 |
| `unsigned char` | ```unsigned char`'' |
|
| 894 |
| `signed char` | ```signed char`'' |
|
| 895 |
| `char8_t` | ```char8_t`'' |
|
| 896 |
| `char16_t` | ```char16_t`'' |
|
|
|
|
| 932 |
[*Note 2*: It is *implementation-defined* whether objects of `char`
|
| 933 |
type are represented as signed or unsigned quantities. The `signed`
|
| 934 |
specifier forces `char` objects to be signed; it is redundant in other
|
| 935 |
contexts. — *end note*]
|
| 936 |
|
| 937 |
+
#### Pack indexing specifier <a id="dcl.type.pack.index">[[dcl.type.pack.index]]</a>
|
| 938 |
+
|
| 939 |
+
``` bnf
|
| 940 |
+
pack-index-specifier:
|
| 941 |
+
typedef-name '...' '[' constant-expression ']'
|
| 942 |
+
```
|
| 943 |
+
|
| 944 |
+
The *typedef-name* P in a *pack-index-specifier* shall denote a pack.
|
| 945 |
+
|
| 946 |
+
The *constant-expression* shall be a converted constant expression
|
| 947 |
+
[[expr.const]] of type `std::size_t` whose value V, termed the index, is
|
| 948 |
+
such that 0 ≤ V < `sizeof...($P$)`.
|
| 949 |
+
|
| 950 |
+
A *pack-index-specifier* is a pack expansion [[temp.variadic]].
|
| 951 |
+
|
| 952 |
+
[*Note 1*: The *pack-index-specifier* denotes the type of the Vᵗʰ
|
| 953 |
+
element of the pack. — *end note*]
|
| 954 |
+
|
| 955 |
#### Elaborated type specifiers <a id="dcl.type.elab">[[dcl.type.elab]]</a>
|
| 956 |
|
| 957 |
``` bnf
|
| 958 |
elaborated-type-specifier:
|
| 959 |
class-key attribute-specifier-seqₒₚₜ nested-name-specifierₒₚₜ identifier
|
|
|
|
| 966 |
*identifier* (if any) and those of its *nested-name-specifier* and
|
| 967 |
*simple-template-id* (if any).
|
| 968 |
|
| 969 |
If an *elaborated-type-specifier* is the sole constituent of a
|
| 970 |
declaration, the declaration is ill-formed unless it is an explicit
|
| 971 |
+
specialization [[temp.expl.spec]], a partial specialization
|
| 972 |
+
[[temp.spec.partial]], an explicit instantiation [[temp.explicit]], or
|
| 973 |
+
it has one of the following forms:
|
| 974 |
|
| 975 |
``` bnf
|
| 976 |
class-key attribute-specifier-seqₒₚₜ identifier ';'
|
| 977 |
class-key attribute-specifier-seqₒₚₜ simple-template-id ';'
|
| 978 |
```
|
| 979 |
|
| 980 |
In the first case, the *elaborated-type-specifier* declares the
|
| 981 |
*identifier* as a *class-name*. The second case shall appear only in an
|
| 982 |
*explicit-specialization* [[temp.expl.spec]] or in a
|
| 983 |
+
*template-declaration* (where it declares a partial specialization). The
|
| 984 |
+
*attribute-specifier-seq*, if any, appertains to the class or template
|
| 985 |
+
being declared.
|
| 986 |
|
| 987 |
Otherwise, an *elaborated-type-specifier* E shall not have an
|
| 988 |
*attribute-specifier-seq*. If E contains an *identifier* but no
|
| 989 |
*nested-name-specifier* and (unqualified) lookup for the *identifier*
|
| 990 |
finds nothing, E shall not be introduced by the `enum` keyword and
|
| 991 |
declares the *identifier* as a *class-name*. The target scope of E is
|
| 992 |
the nearest enclosing namespace or block scope.
|
| 993 |
|
| 994 |
+
A *friend-type-specifier* that is an *elaborated-type-specifier* shall
|
| 995 |
+
have one of the following forms:
|
|
|
|
| 996 |
|
| 997 |
``` bnf
|
| 998 |
+
class-key nested-name-specifierₒₚₜ identifier
|
| 999 |
+
class-key simple-template-id
|
| 1000 |
+
class-key nested-name-specifier templateₒₚₜ simple-template-id
|
| 1001 |
```
|
| 1002 |
|
| 1003 |
Any unqualified lookup for the *identifier* (in the first case) does not
|
| 1004 |
+
consider scopes that contain the nearest enclosing namespace or block
|
| 1005 |
+
scope; no name is bound.
|
| 1006 |
|
| 1007 |
[*Note 1*: A *using-directive* in the target scope is ignored if it
|
| 1008 |
+
refers to a namespace not contained by that scope. — *end note*]
|
|
|
|
|
|
|
| 1009 |
|
| 1010 |
+
[*Note 2*: [[basic.lookup.elab]] describes how name lookup proceeds in
|
| 1011 |
+
an *elaborated-type-specifier*. An *elaborated-type-specifier* can be
|
| 1012 |
+
used to refer to a previously declared *class-name* or *enum-name* even
|
| 1013 |
+
if the name has been hidden by a non-type declaration. — *end note*]
|
| 1014 |
|
| 1015 |
+
If the *identifier* or *simple-template-id* in an
|
| 1016 |
+
*elaborated-type-specifier* resolves to a *class-name* or *enum-name*,
|
| 1017 |
+
the *elaborated-type-specifier* introduces it into the declaration the
|
| 1018 |
+
same way a *simple-type-specifier* introduces its *type-name*
|
| 1019 |
+
[[dcl.type.simple]]. If the *identifier* or *simple-template-id*
|
| 1020 |
+
resolves to a *typedef-name* [[dcl.typedef]], [[temp.names]], the
|
| 1021 |
+
*elaborated-type-specifier* is ill-formed.
|
| 1022 |
|
| 1023 |
[*Note 3*:
|
| 1024 |
|
| 1025 |
This implies that, within a class template with a template
|
| 1026 |
*type-parameter* `T`, the declaration
|
| 1027 |
|
| 1028 |
``` cpp
|
| 1029 |
friend class T;
|
| 1030 |
```
|
| 1031 |
|
| 1032 |
+
is ill-formed. However, the similar declaration `friend T;` is
|
| 1033 |
+
well-formed [[class.friend]].
|
| 1034 |
|
| 1035 |
— *end note*]
|
| 1036 |
|
| 1037 |
+
The *class-key* or `enum` keyword present in an
|
| 1038 |
*elaborated-type-specifier* shall agree in kind with the declaration to
|
| 1039 |
which the name in the *elaborated-type-specifier* refers. This rule also
|
| 1040 |
applies to the form of *elaborated-type-specifier* that declares a
|
| 1041 |
*class-name* or friend class since it can be construed as referring to
|
| 1042 |
the definition of the class. Thus, in any *elaborated-type-specifier*,
|
|
|
|
| 1068 |
|
| 1069 |
- if E is an unparenthesized *id-expression* naming a structured binding
|
| 1070 |
[[dcl.struct.bind]], `decltype(E)` is the referenced type as given in
|
| 1071 |
the specification of the structured binding declaration;
|
| 1072 |
- otherwise, if E is an unparenthesized *id-expression* naming a
|
| 1073 |
+
constant template parameter [[temp.param]], `decltype(E)` is the type
|
| 1074 |
+
of the template parameter after performing any necessary type
|
| 1075 |
deduction [[dcl.spec.auto]], [[dcl.type.class.deduct]];
|
| 1076 |
- otherwise, if E is an unparenthesized *id-expression* or an
|
| 1077 |
unparenthesized class member access [[expr.ref]], `decltype(E)` is the
|
| 1078 |
type of the entity named by E. If there is no such entity, the program
|
| 1079 |
is ill-formed;
|
| 1080 |
+
- otherwise, if E is an unparenthesized *splice-expression*,
|
| 1081 |
+
`decltype(E)` is the type of the entity, object, or value designated
|
| 1082 |
+
by the *splice-specifier* of E;
|
| 1083 |
- otherwise, if E is an xvalue, `decltype(E)` is `T&&`, where `T` is the
|
| 1084 |
type of E;
|
| 1085 |
- otherwise, if E is an lvalue, `decltype(E)` is `T&`, where `T` is the
|
| 1086 |
type of E;
|
| 1087 |
- otherwise, `decltype(E)` is the type of E.
|
|
|
|
| 1098 |
const A* a = new A();
|
| 1099 |
decltype(foo()) x1 = 17; // type is const int&&
|
| 1100 |
decltype(i) x2; // type is int
|
| 1101 |
decltype(a->x) x3; // type is double
|
| 1102 |
decltype((a->x)) x4 = x3; // type is const double&
|
| 1103 |
+
decltype([:^^x1:]) x5 = 18; // type is const int&&
|
| 1104 |
+
decltype(([:^^x1:])) x6 = 19; // type is const int&
|
| 1105 |
+
|
| 1106 |
+
void f() {
|
| 1107 |
+
[](auto ...pack) {
|
| 1108 |
+
decltype(pack...[0]) x7; // type is int
|
| 1109 |
+
decltype((pack...[0])) x8; // type is int&
|
| 1110 |
+
}(0);
|
| 1111 |
+
}
|
| 1112 |
```
|
| 1113 |
|
| 1114 |
— *end example*]
|
| 1115 |
|
| 1116 |
[*Note 1*: The rules for determining types involving `decltype(auto)`
|
|
|
|
| 1176 |
type-constraintₒₚₜ auto
|
| 1177 |
type-constraintₒₚₜ decltype '(' auto ')'
|
| 1178 |
```
|
| 1179 |
|
| 1180 |
A *placeholder-type-specifier* designates a placeholder type that will
|
| 1181 |
+
be replaced later, typically by deduction from an initializer.
|
| 1182 |
|
| 1183 |
+
The type of a *parameter-declaration* of a
|
| 1184 |
+
|
| 1185 |
+
- function declaration [[dcl.fct]],
|
| 1186 |
+
- *lambda-expression* [[expr.prim.lambda]], or
|
| 1187 |
+
- *template-parameter* [[temp.param]]
|
| 1188 |
+
|
| 1189 |
+
can be declared using a *placeholder-type-specifier* of the form
|
| 1190 |
+
*type-constraint*ₒₚₜ `auto`. The placeholder type shall appear as one
|
| 1191 |
+
of the *decl-specifier*s in the *decl-specifier-seq* or as one of the
|
| 1192 |
+
*type-specifier*s in a *trailing-return-type* that specifies the type
|
| 1193 |
+
that replaces such a *decl-specifier* (see below); the placeholder type
|
| 1194 |
+
is a *generic parameter type placeholder* of the function declaration,
|
| 1195 |
+
*lambda-expression*, or *template-parameter*, respectively.
|
| 1196 |
|
| 1197 |
[*Note 1*: Having a generic parameter type placeholder signifies that
|
| 1198 |
the function is an abbreviated function template [[dcl.fct]] or the
|
| 1199 |
lambda is a generic lambda [[expr.prim.lambda]]. — *end note*]
|
| 1200 |
|
| 1201 |
+
A placeholder type can appear in the *decl-specifier-seq* for a function
|
| 1202 |
+
declarator that includes a *trailing-return-type* [[dcl.fct]].
|
| 1203 |
+
|
| 1204 |
+
A placeholder type can appear in the *decl-specifier-seq* or
|
| 1205 |
+
*type-specifier-seq* in the declared return type of a function
|
| 1206 |
+
declarator that declares a function; the return type of the function is
|
| 1207 |
+
deduced from non-discarded `return` statements, if any, in the body of
|
| 1208 |
+
the function [[stmt.if]].
|
|
|
|
|
|
|
| 1209 |
|
| 1210 |
The type of a variable declared using a placeholder type is deduced from
|
| 1211 |
its initializer. This use is allowed in an initializing declaration
|
| 1212 |
[[dcl.init]] of a variable. The placeholder type shall appear as one of
|
| 1213 |
+
the *decl-specifier*s in the *decl-specifier-seq* or as one of the
|
| 1214 |
+
*type-specifier*s in a *trailing-return-type* that specifies the type
|
| 1215 |
+
that replaces such a *decl-specifier*; the *decl-specifier-seq* shall be
|
| 1216 |
+
followed by one or more *declarator*s, each of which shall be followed
|
| 1217 |
+
by a non-empty *initializer*.
|
| 1218 |
|
| 1219 |
[*Example 1*:
|
| 1220 |
|
| 1221 |
``` cpp
|
| 1222 |
auto x = 5; // OK, x has type int
|
| 1223 |
const auto *v = &x, u = 6; // OK, v has type const int*, u has type const int
|
| 1224 |
static auto y = 0.0; // OK, y has type double
|
| 1225 |
auto int r; // error: auto is not a storage-class-specifier
|
| 1226 |
auto f() -> int; // OK, f returns int
|
| 1227 |
auto g() { return 0.0; } // OK, g returns double
|
| 1228 |
+
auto (*fp)() -> auto = f; // OK
|
| 1229 |
auto h(); // OK, h's return type will be deduced when it is defined
|
| 1230 |
```
|
| 1231 |
|
| 1232 |
— *end example*]
|
| 1233 |
|
| 1234 |
The `auto` *type-specifier* can also be used to introduce a structured
|
| 1235 |
binding declaration [[dcl.struct.bind]].
|
| 1236 |
|
| 1237 |
+
A placeholder type can also be used in the *type-specifier-seq* of the
|
| 1238 |
+
*new-type-id* or in the *type-id* of a *new-expression* [[expr.new]]. In
|
| 1239 |
+
such a *type-id*, the placeholder type shall appear as one of the
|
| 1240 |
+
*type-specifier*s in the *type-specifier-seq* or as one of the
|
| 1241 |
+
*type-specifier*s in a *trailing-return-type* that specifies the type
|
| 1242 |
+
that replaces such a *type-specifier*.
|
| 1243 |
+
|
| 1244 |
+
The `auto` *type-specifier* can also be used as the
|
| 1245 |
+
*simple-type-specifier* in an explicit type conversion (functional
|
| 1246 |
+
notation) [[expr.type.conv]].
|
| 1247 |
|
| 1248 |
A program that uses a placeholder type in a context not explicitly
|
| 1249 |
allowed in [[dcl.spec.auto]] is ill-formed.
|
| 1250 |
|
| 1251 |
If the *init-declarator-list* contains more than one *init-declarator*,
|
|
|
|
| 1309 |
}
|
| 1310 |
```
|
| 1311 |
|
| 1312 |
— *end example*]
|
| 1313 |
|
| 1314 |
+
A result binding never has an undeduced placeholder type
|
| 1315 |
+
[[dcl.contract.res]].
|
| 1316 |
+
|
| 1317 |
+
[*Example 5*:
|
| 1318 |
+
|
| 1319 |
+
``` cpp
|
| 1320 |
+
auto f()
|
| 1321 |
+
post(r : r == 7) // OK
|
| 1322 |
+
{
|
| 1323 |
+
return 7;
|
| 1324 |
+
}
|
| 1325 |
+
```
|
| 1326 |
+
|
| 1327 |
+
— *end example*]
|
| 1328 |
+
|
| 1329 |
Return type deduction for a templated function with a placeholder in its
|
| 1330 |
declared type occurs when the definition is instantiated even if the
|
| 1331 |
function body contains a `return` statement with a non-type-dependent
|
| 1332 |
operand.
|
| 1333 |
|
|
|
|
| 1335 |
template will cause an implicit instantiation. Any errors that arise
|
| 1336 |
from this instantiation are not in the immediate context of the function
|
| 1337 |
type and can result in the program being ill-formed
|
| 1338 |
[[temp.deduct]]. — *end note*]
|
| 1339 |
|
| 1340 |
+
[*Example 6*:
|
| 1341 |
|
| 1342 |
``` cpp
|
| 1343 |
template <class T> auto f(T t) { return t; } // return type deduced at instantiation time
|
| 1344 |
typedef decltype(f(1)) fint_t; // instantiates f<int> to deduce return type
|
| 1345 |
template<class T> auto f(T* t) { return *t; }
|
|
|
|
| 1352 |
If a function or function template F has a declared return type that
|
| 1353 |
uses a placeholder type, redeclarations or specializations of F shall
|
| 1354 |
use that placeholder type, not a deduced type; otherwise, they shall not
|
| 1355 |
use a placeholder type.
|
| 1356 |
|
| 1357 |
+
[*Example 7*:
|
| 1358 |
|
| 1359 |
``` cpp
|
| 1360 |
auto f();
|
| 1361 |
auto f() { return 42; } // return type is int
|
| 1362 |
auto f(); // OK
|
|
|
|
| 1397 |
An explicit instantiation declaration [[temp.explicit]] does not cause
|
| 1398 |
the instantiation of an entity declared using a placeholder type, but it
|
| 1399 |
also does not prevent that entity from being instantiated as needed to
|
| 1400 |
determine its type.
|
| 1401 |
|
| 1402 |
+
[*Example 8*:
|
| 1403 |
|
| 1404 |
``` cpp
|
| 1405 |
template <typename T> auto f(T t) { return t; }
|
| 1406 |
extern template auto f(int); // does not instantiate f<int>
|
| 1407 |
int (*p)(int) = f; // instantiates f<int> to determine its return type, but an explicit
|
|
|
|
| 1447 |
single brace-enclosed *assignment-expression* and E is the
|
| 1448 |
*assignment-expression*.
|
| 1449 |
- If the initializer is a parenthesized *expression-list*, the
|
| 1450 |
*expression-list* shall be a single *assignment-expression* and E is
|
| 1451 |
the *assignment-expression*.
|
| 1452 |
+
- For a constant template parameter declared with a type that contains a
|
| 1453 |
+
placeholder type, `T` is the declared type of the constant template
|
| 1454 |
parameter and E is the corresponding template argument.
|
| 1455 |
|
| 1456 |
`T` shall not be an array type.
|
| 1457 |
|
| 1458 |
If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
|
| 1459 |
`auto`, the deduced type T' replacing `T` is determined using the rules
|
| 1460 |
for template argument deduction. If the initialization is
|
| 1461 |
copy-list-initialization, a declaration of `std::initializer_list` shall
|
| 1462 |
precede [[basic.lookup.general]] the *placeholder-type-specifier*.
|
| 1463 |
+
Obtain `P` from `T` by replacing the occurrence of *type-constraint*ₒₚₜ
|
| 1464 |
+
`auto` either with a new invented type template parameter `U` or, if the
|
| 1465 |
+
initialization is copy-list-initialization, with
|
| 1466 |
+
`std::initializer_list<U>`. Deduce a value for `U` using the rules of
|
| 1467 |
+
template argument deduction from a function call [[temp.deduct.call]],
|
| 1468 |
+
where `P` is a function template parameter type and the corresponding
|
| 1469 |
+
argument is E. If the deduction fails, the declaration is ill-formed.
|
| 1470 |
+
Otherwise, T' is obtained by substituting the deduced `U` into `P`.
|
|
|
|
| 1471 |
|
| 1472 |
+
[*Example 9*:
|
| 1473 |
|
| 1474 |
``` cpp
|
| 1475 |
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
|
| 1476 |
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
|
| 1477 |
auto x3{ 1, 2 }; // error: not a single element
|
|
|
|
| 1479 |
auto x5{ 3 }; // decltype(x5) is int
|
| 1480 |
```
|
| 1481 |
|
| 1482 |
— *end example*]
|
| 1483 |
|
| 1484 |
+
[*Example 10*:
|
| 1485 |
|
| 1486 |
``` cpp
|
| 1487 |
const auto &i = expr;
|
| 1488 |
```
|
| 1489 |
|
|
|
|
| 1499 |
If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
|
| 1500 |
`decltype(auto)`, `T` shall be the placeholder alone. The type deduced
|
| 1501 |
for `T` is determined as described in [[dcl.type.decltype]], as though
|
| 1502 |
E had been the operand of the `decltype`.
|
| 1503 |
|
| 1504 |
+
[*Example 11*:
|
| 1505 |
|
| 1506 |
``` cpp
|
| 1507 |
int i;
|
| 1508 |
int&& f();
|
| 1509 |
auto x2a(i); // decltype(x2a) is int
|
|
|
|
| 1578 |
container e{5, 6}; // error: int is not an iterator
|
| 1579 |
```
|
| 1580 |
|
| 1581 |
— *end example*]
|
| 1582 |
|
| 1583 |
+
#### Type splicing <a id="dcl.type.splice">[[dcl.type.splice]]</a>
|
| 1584 |
+
|
| 1585 |
+
``` bnf
|
| 1586 |
+
splice-type-specifier:
|
| 1587 |
+
typenameₒₚₜ splice-specifier
|
| 1588 |
+
typenameₒₚₜ splice-specialization-specifier
|
| 1589 |
+
```
|
| 1590 |
+
|
| 1591 |
+
A *splice-specifier* or *splice-specialization-specifier* immediately
|
| 1592 |
+
followed by `::` is never interpreted as part of a
|
| 1593 |
+
*splice-type-specifier*. A *splice-specifier* or
|
| 1594 |
+
*splice-specialization-specifier* not preceded by `typename` is only
|
| 1595 |
+
interpreted as a *splice-type-specifier* within a type-only context
|
| 1596 |
+
[[temp.res.general]].
|
| 1597 |
+
|
| 1598 |
+
[*Example 1*:
|
| 1599 |
+
|
| 1600 |
+
``` cpp
|
| 1601 |
+
template<std::meta::info R> void tfn() {
|
| 1602 |
+
typename [:R:]::type m; // OK, typename applies to the qualified name
|
| 1603 |
+
}
|
| 1604 |
+
|
| 1605 |
+
struct S { using type = int; };
|
| 1606 |
+
void fn() {
|
| 1607 |
+
[:^^S::type:] *var; // error: [:^^ S::type:] is an expression
|
| 1608 |
+
typename [:^^S::type:] *var; // OK, declares variable with type int*
|
| 1609 |
+
}
|
| 1610 |
+
|
| 1611 |
+
using alias = [:^^S::type:]; // OK, type-only context
|
| 1612 |
+
```
|
| 1613 |
+
|
| 1614 |
+
— *end example*]
|
| 1615 |
+
|
| 1616 |
+
For a *splice-type-specifier* of the form `typename`ₒₚₜ
|
| 1617 |
+
*splice-specifier*, the *splice-specifier* shall designate a type, a
|
| 1618 |
+
class template, or an alias template. The *splice-type-specifier*
|
| 1619 |
+
designates the same entity as the *splice-specifier*.
|
| 1620 |
+
|
| 1621 |
+
For a *splice-type-specifier* of the form `typename`ₒₚₜ
|
| 1622 |
+
*splice-specialization-specifier*, the *splice-specifier* of the
|
| 1623 |
+
*splice-specialization-specifier* shall designate a template `T` that is
|
| 1624 |
+
either a class template or an alias template. The
|
| 1625 |
+
*splice-type-specifier* designates the specialization of `T`
|
| 1626 |
+
corresponding to the template argument list of the
|
| 1627 |
+
*splice-specialization-specifier*.
|
| 1628 |
+
|