- tmp/tmpn3fxb8gh/{from.md → to.md} +227 -305
tmp/tmpn3fxb8gh/{from.md → to.md}
RENAMED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
## Specifiers <a id="dcl.spec">[[dcl.spec]]</a>
|
| 2 |
|
|
|
|
|
|
|
| 3 |
The specifiers that can be used in a declaration are
|
| 4 |
|
| 5 |
``` bnf
|
| 6 |
decl-specifier:
|
| 7 |
storage-class-specifier
|
|
@@ -93,15 +95,14 @@ At most one *storage-class-specifier* shall appear in a given
|
|
| 93 |
`static` or `extern`. If `thread_local` appears in any declaration of a
|
| 94 |
variable it shall be present in all declarations of that entity. If a
|
| 95 |
*storage-class-specifier* appears in a *decl-specifier-seq*, there can
|
| 96 |
be no `typedef` specifier in the same *decl-specifier-seq* and the
|
| 97 |
*init-declarator-list* or *member-declarator-list* of the declaration
|
| 98 |
-
shall not be empty (except for an anonymous union declared in a
|
| 99 |
-
namespace
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
declared by other specifiers.
|
| 103 |
|
| 104 |
[*Note 1*: See [[temp.expl.spec]] and [[temp.explicit]] for
|
| 105 |
restrictions in explicit specializations and explicit instantiations,
|
| 106 |
respectively. — *end note*]
|
| 107 |
|
|
@@ -137,14 +138,15 @@ a name declared with an `extern` specifier, see [[basic.link]].
|
|
| 137 |
|
| 138 |
[*Note 3*: The `extern` keyword can also be used in
|
| 139 |
*explicit-instantiation*s and *linkage-specification*s, but it is not a
|
| 140 |
*storage-class-specifier* in such contexts. — *end note*]
|
| 141 |
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
|
|
|
| 146 |
|
| 147 |
[*Example 1*:
|
| 148 |
|
| 149 |
``` cpp
|
| 150 |
static char* f(); // f() has internal linkage
|
|
@@ -215,15 +217,15 @@ class X {
|
|
| 215 |
};
|
| 216 |
```
|
| 217 |
|
| 218 |
— *end example*]
|
| 219 |
|
| 220 |
-
[*Note
|
| 221 |
`const` specifier applied to the containing class object and permits
|
| 222 |
modification of the mutable class member even though the rest of the
|
| 223 |
-
object is const
|
| 224 |
-
[[dcl.type.cv]]
|
| 225 |
|
| 226 |
### Function specifiers <a id="dcl.fct.spec">[[dcl.fct.spec]]</a>
|
| 227 |
|
| 228 |
A *function-specifier* can be used only in a function declaration.
|
| 229 |
|
|
@@ -238,11 +240,11 @@ explicit-specifier:
|
|
| 238 |
explicit '(' constant-expression ')'
|
| 239 |
explicit
|
| 240 |
```
|
| 241 |
|
| 242 |
The `virtual` specifier shall be used only in the initial declaration of
|
| 243 |
-
a non-static
|
| 244 |
|
| 245 |
An *explicit-specifier* shall be used only in the declaration of a
|
| 246 |
constructor or conversion function within its class definition; see
|
| 247 |
[[class.conv.ctor]] and [[class.conv.fct]].
|
| 248 |
|
|
@@ -253,10 +255,21 @@ shall be a contextually converted constant expression of type `bool`
|
|
| 253 |
`explicit(true)`. If the constant expression evaluates to `true`, the
|
| 254 |
function is explicit. Otherwise, the function is not explicit. A `(`
|
| 255 |
token that follows `explicit` is parsed as part of the
|
| 256 |
*explicit-specifier*.
|
| 257 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
### The `typedef` specifier <a id="dcl.typedef">[[dcl.typedef]]</a>
|
| 259 |
|
| 260 |
Declarations containing the *decl-specifier* `typedef` declare
|
| 261 |
identifiers that can be used later for naming fundamental
|
| 262 |
[[basic.fundamental]] or compound [[basic.compound]] types. The
|
|
@@ -299,118 +312,43 @@ are all correct declarations; the type of `distance` is `int` and that
|
|
| 299 |
of `metricp` is “pointer to `int`”.
|
| 300 |
|
| 301 |
— *end example*]
|
| 302 |
|
| 303 |
A *typedef-name* can also be introduced by an *alias-declaration*. The
|
| 304 |
-
*identifier* following the `using` keyword
|
| 305 |
-
the optional *attribute-specifier-seq* following
|
| 306 |
-
appertains to that *typedef-name*. Such a
|
| 307 |
-
semantics as if it were introduced by the
|
| 308 |
-
particular, it does not define a new type.
|
| 309 |
|
| 310 |
[*Example 2*:
|
| 311 |
|
| 312 |
``` cpp
|
| 313 |
using handler_t = void (*)(int);
|
| 314 |
extern handler_t ignore;
|
| 315 |
extern void (*ignore)(int); // redeclare ignore
|
| 316 |
-
|
|
|
|
| 317 |
```
|
| 318 |
|
| 319 |
— *end example*]
|
| 320 |
|
| 321 |
The *defining-type-specifier-seq* of the *defining-type-id* shall not
|
| 322 |
define a class or enumeration if the *alias-declaration* is the
|
| 323 |
*declaration* of a *template-declaration*.
|
| 324 |
|
| 325 |
-
In a given non-class scope, a `typedef` specifier can be used to
|
| 326 |
-
redeclare the name of any type declared in that scope to refer to the
|
| 327 |
-
type to which it already refers.
|
| 328 |
-
|
| 329 |
-
[*Example 3*:
|
| 330 |
-
|
| 331 |
-
``` cpp
|
| 332 |
-
typedef struct s { ... } s;
|
| 333 |
-
typedef int I;
|
| 334 |
-
typedef int I;
|
| 335 |
-
typedef I I;
|
| 336 |
-
```
|
| 337 |
-
|
| 338 |
-
— *end example*]
|
| 339 |
-
|
| 340 |
-
In a given class scope, a `typedef` specifier can be used to redeclare
|
| 341 |
-
any *class-name* declared in that scope that is not also a
|
| 342 |
-
*typedef-name* to refer to the type to which it already refers.
|
| 343 |
-
|
| 344 |
-
[*Example 4*:
|
| 345 |
-
|
| 346 |
-
``` cpp
|
| 347 |
-
struct S {
|
| 348 |
-
typedef struct A { } A; // OK
|
| 349 |
-
typedef struct B B; // OK
|
| 350 |
-
typedef A A; // error
|
| 351 |
-
};
|
| 352 |
-
```
|
| 353 |
-
|
| 354 |
-
— *end example*]
|
| 355 |
-
|
| 356 |
-
If a `typedef` specifier is used to redeclare in a given scope an entity
|
| 357 |
-
that can be referenced using an *elaborated-type-specifier*, the entity
|
| 358 |
-
can continue to be referenced by an *elaborated-type-specifier* or as an
|
| 359 |
-
enumeration or class name in an enumeration or class definition
|
| 360 |
-
respectively.
|
| 361 |
-
|
| 362 |
-
[*Example 5*:
|
| 363 |
-
|
| 364 |
-
``` cpp
|
| 365 |
-
struct S;
|
| 366 |
-
typedef struct S S;
|
| 367 |
-
int main() {
|
| 368 |
-
struct S* p; // OK
|
| 369 |
-
}
|
| 370 |
-
struct S { }; // OK
|
| 371 |
-
```
|
| 372 |
-
|
| 373 |
-
— *end example*]
|
| 374 |
-
|
| 375 |
-
In a given scope, a `typedef` specifier shall not be used to redeclare
|
| 376 |
-
the name of any type declared in that scope to refer to a different
|
| 377 |
-
type.
|
| 378 |
-
|
| 379 |
-
[*Example 6*:
|
| 380 |
-
|
| 381 |
-
``` cpp
|
| 382 |
-
class complex { ... };
|
| 383 |
-
typedef int complex; // error: redefinition
|
| 384 |
-
```
|
| 385 |
-
|
| 386 |
-
— *end example*]
|
| 387 |
-
|
| 388 |
-
Similarly, in a given scope, a class or enumeration shall not be
|
| 389 |
-
declared with the same name as a *typedef-name* that is declared in that
|
| 390 |
-
scope and refers to a type other than the class or enumeration itself.
|
| 391 |
-
|
| 392 |
-
[*Example 7*:
|
| 393 |
-
|
| 394 |
-
``` cpp
|
| 395 |
-
typedef int complex;
|
| 396 |
-
class complex { ... }; // error: redefinition
|
| 397 |
-
```
|
| 398 |
-
|
| 399 |
-
— *end example*]
|
| 400 |
-
|
| 401 |
A *simple-template-id* is only a *typedef-name* if its *template-name*
|
| 402 |
names an alias template or a template *template-parameter*.
|
| 403 |
|
| 404 |
[*Note 1*: A *simple-template-id* that names a class template
|
| 405 |
specialization is a *class-name* [[class.name]]. If a *typedef-name* is
|
| 406 |
used to identify the subject of an *elaborated-type-specifier*
|
| 407 |
[[dcl.type.elab]], a class definition [[class]], a constructor
|
| 408 |
declaration [[class.ctor]], or a destructor declaration [[class.dtor]],
|
| 409 |
the program is ill-formed. — *end note*]
|
| 410 |
|
| 411 |
-
[*Example
|
| 412 |
|
| 413 |
``` cpp
|
| 414 |
struct S {
|
| 415 |
S();
|
| 416 |
~S();
|
|
@@ -422,23 +360,23 @@ S a = T(); // OK
|
|
| 422 |
struct T * p; // error
|
| 423 |
```
|
| 424 |
|
| 425 |
— *end example*]
|
| 426 |
|
| 427 |
-
|
| 428 |
-
first *typedef-name* declared by the declaration to be
|
| 429 |
-
|
| 430 |
|
| 431 |
[*Note 2*: A typedef declaration involving a *lambda-expression* does
|
| 432 |
not itself define the associated closure type, and so the closure type
|
| 433 |
-
is not given a name for linkage purposes. — *end note*]
|
| 434 |
|
| 435 |
-
[*Example
|
| 436 |
|
| 437 |
``` cpp
|
| 438 |
-
typedef struct { } *ps, S; // S is the
|
| 439 |
-
typedef decltype([]{}) C; // the closure type has no name for linkage purposes
|
| 440 |
```
|
| 441 |
|
| 442 |
— *end example*]
|
| 443 |
|
| 444 |
An unnamed class with a typedef name for linkage purposes shall not
|
|
@@ -449,11 +387,11 @@ An unnamed class with a typedef name for linkage purposes shall not
|
|
| 449 |
- contain a *lambda-expression*,
|
| 450 |
|
| 451 |
and all member classes shall also satisfy these requirements
|
| 452 |
(recursively).
|
| 453 |
|
| 454 |
-
[*Example
|
| 455 |
|
| 456 |
``` cpp
|
| 457 |
typedef struct {
|
| 458 |
int f() {}
|
| 459 |
} X; // error: struct with typedef name for linkage has member functions
|
|
@@ -486,58 +424,52 @@ specifier. — *end note*]
|
|
| 486 |
`constexpr`. — *end note*]
|
| 487 |
|
| 488 |
[*Example 1*:
|
| 489 |
|
| 490 |
``` cpp
|
| 491 |
-
constexpr void square(int &x); // OK
|
| 492 |
-
constexpr int bufsz = 1024; // OK
|
| 493 |
constexpr struct pixel { // error: pixel is a type
|
| 494 |
int x;
|
| 495 |
int y;
|
| 496 |
-
constexpr pixel(int); // OK
|
| 497 |
};
|
| 498 |
constexpr pixel::pixel(int a)
|
| 499 |
-
: x(a), y(x) // OK
|
| 500 |
{ square(x); }
|
| 501 |
constexpr pixel small(2); // error: square not defined, so small(2)
|
| 502 |
// not constant[expr.const] so constexpr not satisfied
|
| 503 |
|
| 504 |
-
constexpr void square(int &x) { // OK
|
| 505 |
x *= x;
|
| 506 |
}
|
| 507 |
-
constexpr pixel large(4); // OK
|
| 508 |
int next(constexpr int x) { // error: not for parameters
|
| 509 |
return x + 1;
|
| 510 |
}
|
| 511 |
extern constexpr int memsz; // error: not a definition
|
| 512 |
```
|
| 513 |
|
| 514 |
— *end example*]
|
| 515 |
|
| 516 |
A `constexpr` or `consteval` specifier used in the declaration of a
|
| 517 |
-
function declares that function to be a *constexpr function*.
|
| 518 |
-
or constructor declared with the `consteval` specifier is called an
|
| 519 |
-
*immediate function*. A destructor, an allocation function, or a
|
| 520 |
-
deallocation function shall not be declared with the `consteval`
|
| 521 |
-
specifier.
|
| 522 |
|
| 523 |
-
|
| 524 |
-
|
| 525 |
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
- it shall not be a coroutine [[dcl.fct.def.coroutine]];
|
| 529 |
-
- if the function is a constructor or destructor, its class shall not
|
| 530 |
-
have any virtual base classes;
|
| 531 |
-
- its *function-body* shall not enclose [[stmt.pre]]
|
| 532 |
-
- a `goto` statement,
|
| 533 |
-
- an identifier label [[stmt.label]],
|
| 534 |
-
- a definition of a variable of non-literal type or of static or
|
| 535 |
-
thread storage duration.
|
| 536 |
|
| 537 |
-
|
| 538 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 539 |
|
| 540 |
[*Example 2*:
|
| 541 |
|
| 542 |
``` cpp
|
| 543 |
constexpr int square(int x)
|
|
@@ -547,14 +479,17 @@ constexpr long long_max()
|
|
| 547 |
constexpr int abs(int x) {
|
| 548 |
if (x < 0)
|
| 549 |
x = -x;
|
| 550 |
return x; // OK
|
| 551 |
}
|
| 552 |
-
constexpr int
|
| 553 |
-
|
|
|
|
| 554 |
return value;
|
| 555 |
}
|
|
|
|
|
|
|
| 556 |
constexpr int uninit() {
|
| 557 |
struct { int a; } s;
|
| 558 |
return s.a; // error: uninitialized read of s.a
|
| 559 |
}
|
| 560 |
constexpr int prev(int x)
|
|
@@ -566,77 +501,10 @@ constexpr int g(int x, int n) { // OK
|
|
| 566 |
}
|
| 567 |
```
|
| 568 |
|
| 569 |
— *end example*]
|
| 570 |
|
| 571 |
-
The definition of a constexpr constructor whose *function-body* is not
|
| 572 |
-
`= delete` shall additionally satisfy the following requirements:
|
| 573 |
-
|
| 574 |
-
- for a non-delegating constructor, every constructor selected to
|
| 575 |
-
initialize non-static data members and base class subobjects shall be
|
| 576 |
-
a constexpr constructor;
|
| 577 |
-
- for a delegating constructor, the target constructor shall be a
|
| 578 |
-
constexpr constructor.
|
| 579 |
-
|
| 580 |
-
[*Example 3*:
|
| 581 |
-
|
| 582 |
-
``` cpp
|
| 583 |
-
struct Length {
|
| 584 |
-
constexpr explicit Length(int i = 0) : val(i) { }
|
| 585 |
-
private:
|
| 586 |
-
int val;
|
| 587 |
-
};
|
| 588 |
-
```
|
| 589 |
-
|
| 590 |
-
— *end example*]
|
| 591 |
-
|
| 592 |
-
The definition of a constexpr destructor whose *function-body* is not
|
| 593 |
-
`= delete` shall additionally satisfy the following requirement:
|
| 594 |
-
|
| 595 |
-
- for every subobject of class type or (possibly multi-dimensional)
|
| 596 |
-
array thereof, that class type shall have a constexpr destructor.
|
| 597 |
-
|
| 598 |
-
For a constexpr function or constexpr constructor that is neither
|
| 599 |
-
defaulted nor a template, if no argument values exist such that an
|
| 600 |
-
invocation of the function or constructor could be an evaluated
|
| 601 |
-
subexpression of a core constant expression [[expr.const]], or, for a
|
| 602 |
-
constructor, an evaluated subexpression of the initialization
|
| 603 |
-
full-expression of some constant-initialized object
|
| 604 |
-
[[basic.start.static]], the program is ill-formed, no diagnostic
|
| 605 |
-
required.
|
| 606 |
-
|
| 607 |
-
[*Example 4*:
|
| 608 |
-
|
| 609 |
-
``` cpp
|
| 610 |
-
constexpr int f(bool b)
|
| 611 |
-
{ return b ? throw 0 : 0; } // OK
|
| 612 |
-
constexpr int f() { return f(true); } // ill-formed, no diagnostic required
|
| 613 |
-
|
| 614 |
-
struct B {
|
| 615 |
-
constexpr B(int x) : i(0) { } // x is unused
|
| 616 |
-
int i;
|
| 617 |
-
};
|
| 618 |
-
|
| 619 |
-
int global;
|
| 620 |
-
|
| 621 |
-
struct D : B {
|
| 622 |
-
constexpr D() : B(global) { } // ill-formed, no diagnostic required
|
| 623 |
-
// lvalue-to-rvalue conversion on non-constant global
|
| 624 |
-
};
|
| 625 |
-
```
|
| 626 |
-
|
| 627 |
-
— *end example*]
|
| 628 |
-
|
| 629 |
-
If the instantiated template specialization of a constexpr function
|
| 630 |
-
template or member function of a class template would fail to satisfy
|
| 631 |
-
the requirements for a constexpr function, that specialization is still
|
| 632 |
-
a constexpr function, even though a call to such a function cannot
|
| 633 |
-
appear in a constant expression. If no specialization of the template
|
| 634 |
-
would satisfy the requirements for a constexpr function when considered
|
| 635 |
-
as a non-template function, the template is ill-formed, no diagnostic
|
| 636 |
-
required.
|
| 637 |
-
|
| 638 |
An invocation of a constexpr function in a given context produces the
|
| 639 |
same result as an invocation of an equivalent non-constexpr function in
|
| 640 |
the same context in all respects except that
|
| 641 |
|
| 642 |
- an invocation of a constexpr function can appear in a constant
|
|
@@ -647,14 +515,18 @@ the same context in all respects except that
|
|
| 647 |
[*Note 4*: Declaring a function constexpr can change whether an
|
| 648 |
expression is a constant expression. This can indirectly cause calls to
|
| 649 |
`std::is_constant_evaluated` within an invocation of the function to
|
| 650 |
produce a different value. — *end note*]
|
| 651 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 652 |
The `constexpr` and `consteval` specifiers have no effect on the type of
|
| 653 |
a constexpr function.
|
| 654 |
|
| 655 |
-
[*Example
|
| 656 |
|
| 657 |
``` cpp
|
| 658 |
constexpr int bar(int x, int y) // OK
|
| 659 |
{ return x + y + x*y; }
|
| 660 |
// ...
|
|
@@ -666,13 +538,15 @@ int bar(int x, int y) // error: redefinition of bar
|
|
| 666 |
|
| 667 |
A `constexpr` specifier used in an object declaration declares the
|
| 668 |
object as const. Such an object shall have literal type and shall be
|
| 669 |
initialized. In any `constexpr` variable declaration, the
|
| 670 |
full-expression of the initialization shall be a constant expression
|
| 671 |
-
[[expr.const]]. A `constexpr` variable
|
|
|
|
|
|
|
| 672 |
|
| 673 |
-
[*Example
|
| 674 |
|
| 675 |
``` cpp
|
| 676 |
struct pixel {
|
| 677 |
int x, y;
|
| 678 |
};
|
|
@@ -689,15 +563,16 @@ variable with static or thread storage duration. If the specifier is
|
|
| 689 |
applied to any declaration of a variable, it shall be applied to the
|
| 690 |
initializing declaration. No diagnostic is required if no `constinit`
|
| 691 |
declaration is reachable at the point of the initializing declaration.
|
| 692 |
|
| 693 |
If a variable declared with the `constinit` specifier has dynamic
|
| 694 |
-
initialization [[basic.start.dynamic]], the program is ill-formed
|
|
|
|
|
|
|
| 695 |
|
| 696 |
[*Note 1*: The `constinit` specifier ensures that the variable is
|
| 697 |
-
initialized during static initialization
|
| 698 |
-
[[basic.start.static]]. — *end note*]
|
| 699 |
|
| 700 |
[*Example 1*:
|
| 701 |
|
| 702 |
``` cpp
|
| 703 |
const char * g() { return "dynamic initialization"; }
|
|
@@ -711,11 +586,11 @@ constinit const char * d = f(false); // error
|
|
| 711 |
### The `inline` specifier <a id="dcl.inline">[[dcl.inline]]</a>
|
| 712 |
|
| 713 |
The `inline` specifier shall be applied only to the declaration of a
|
| 714 |
variable or function.
|
| 715 |
|
| 716 |
-
A function declaration
|
| 717 |
with an `inline` specifier declares an *inline function*. The inline
|
| 718 |
specifier indicates to the implementation that inline substitution of
|
| 719 |
the function body at the point of call is to be preferred to the usual
|
| 720 |
function call mechanism. An implementation is not required to perform
|
| 721 |
this inline substitution at the point of call; however, even if this
|
|
@@ -740,29 +615,30 @@ function or variable with external or module linkage is declared inline
|
|
| 740 |
in one definition domain, an inline declaration of it shall be reachable
|
| 741 |
from the end of every definition domain in which it is declared; no
|
| 742 |
diagnostic is required.
|
| 743 |
|
| 744 |
[*Note 2*: A call to an inline function or a use of an inline variable
|
| 745 |
-
|
| 746 |
translation unit. — *end note*]
|
| 747 |
|
| 748 |
[*Note 3*: An inline function or variable with external or module
|
| 749 |
-
linkage
|
| 750 |
-
|
| 751 |
-
|
| 752 |
-
|
| 753 |
-
translation unit. — *end note*]
|
| 754 |
|
| 755 |
If an inline function or variable that is attached to a named module is
|
| 756 |
declared in a definition domain, it shall be defined in that domain.
|
| 757 |
|
| 758 |
[*Note 4*: A constexpr function [[dcl.constexpr]] is implicitly inline.
|
| 759 |
In the global module, a function defined within a class definition is
|
| 760 |
-
implicitly inline
|
| 761 |
|
| 762 |
### Type specifiers <a id="dcl.type">[[dcl.type]]</a>
|
| 763 |
|
|
|
|
|
|
|
| 764 |
The type-specifiers are
|
| 765 |
|
| 766 |
``` bnf
|
| 767 |
type-specifier:
|
| 768 |
simple-type-specifier
|
|
@@ -817,11 +693,11 @@ function, at least one *defining-type-specifier* that is not a
|
|
| 817 |
complete *decl-specifier-seq*.[^1]
|
| 818 |
|
| 819 |
[*Note 1*: *enum-specifier*s, *class-specifier*s, and
|
| 820 |
*typename-specifier*s are discussed in [[dcl.enum]], [[class]], and
|
| 821 |
[[temp.res]], respectively. The remaining *type-specifier*s are
|
| 822 |
-
discussed in the rest of
|
| 823 |
|
| 824 |
#### The *cv-qualifier*s <a id="dcl.type.cv">[[dcl.type.cv]]</a>
|
| 825 |
|
| 826 |
There are two *cv-qualifier*s, `const` and `volatile`. Each
|
| 827 |
*cv-qualifier* shall appear at most once in a *cv-qualifier-seq*. If a
|
|
@@ -850,23 +726,24 @@ the object referenced is a non-const object and can be modified through
|
|
| 850 |
some other access path.
|
| 851 |
|
| 852 |
[*Note 4*: Cv-qualifiers are supported by the type system so that they
|
| 853 |
cannot be subverted without casting [[expr.const.cast]]. — *end note*]
|
| 854 |
|
| 855 |
-
Any attempt to modify
|
| 856 |
-
[[expr.
|
| 857 |
-
lifetime [[basic.life]] results in
|
|
|
|
| 858 |
|
| 859 |
[*Example 1*:
|
| 860 |
|
| 861 |
``` cpp
|
| 862 |
const int ci = 3; // cv-qualified (initialized as required)
|
| 863 |
ci = 4; // error: attempt to modify const
|
| 864 |
|
| 865 |
int i = 2; // not cv-qualified
|
| 866 |
const int* cip; // pointer to const int
|
| 867 |
-
cip = &i; // OK
|
| 868 |
*cip = 4; // error: attempt to modify through ptr to const
|
| 869 |
|
| 870 |
int* ip;
|
| 871 |
ip = const_cast<int*>(cip); // cast needed to convert const int* to int*
|
| 872 |
*ip = 4; // defined: *ip points to i, a non-const object
|
|
@@ -944,10 +821,16 @@ type-name:
|
|
| 944 |
class-name
|
| 945 |
enum-name
|
| 946 |
typedef-name
|
| 947 |
```
|
| 948 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 949 |
A *placeholder-type-specifier* is a placeholder for a type to be deduced
|
| 950 |
[[dcl.spec.auto]]. A *type-specifier* of the form `typename`ₒₚₜ
|
| 951 |
*nested-name-specifier*ₒₚₜ *template-name* is a placeholder for a
|
| 952 |
deduced class type [[dcl.type.class.deduct]]. The
|
| 953 |
*nested-name-specifier*, if any, shall be non-dependent and the
|
|
@@ -1030,49 +913,72 @@ contexts. — *end note*]
|
|
| 1030 |
``` bnf
|
| 1031 |
elaborated-type-specifier:
|
| 1032 |
class-key attribute-specifier-seqₒₚₜ nested-name-specifierₒₚₜ identifier
|
| 1033 |
class-key simple-template-id
|
| 1034 |
class-key nested-name-specifier templateₒₚₜ simple-template-id
|
| 1035 |
-
elaborated-enum-specifier
|
| 1036 |
-
```
|
| 1037 |
-
|
| 1038 |
-
``` bnf
|
| 1039 |
-
elaborated-enum-specifier:
|
| 1040 |
enum nested-name-specifierₒₚₜ identifier
|
| 1041 |
```
|
| 1042 |
|
| 1043 |
-
|
| 1044 |
-
*
|
| 1045 |
-
|
| 1046 |
-
|
|
|
|
|
|
|
| 1047 |
specialization [[temp.expl.spec]], an explicit instantiation
|
| 1048 |
[[temp.explicit]] or it has one of the following forms:
|
| 1049 |
|
| 1050 |
``` bnf
|
| 1051 |
class-key attribute-specifier-seqₒₚₜ identifier ';'
|
| 1052 |
-
|
| 1053 |
-
|
| 1054 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1055 |
friend class-key nested-name-specifier templateₒₚₜ simple-template-id ';'
|
| 1056 |
```
|
| 1057 |
|
| 1058 |
-
|
| 1059 |
-
|
| 1060 |
-
*attribute-specifier-seq* are thereafter considered attributes of the
|
| 1061 |
-
class whenever it is named.
|
| 1062 |
|
| 1063 |
-
[*Note 1*:
|
| 1064 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1065 |
|
| 1066 |
If the *identifier* or *simple-template-id* resolves to a *class-name*
|
| 1067 |
or *enum-name*, the *elaborated-type-specifier* introduces it into the
|
| 1068 |
declaration the same way a *simple-type-specifier* introduces its
|
| 1069 |
*type-name* [[dcl.type.simple]]. If the *identifier* or
|
| 1070 |
-
*simple-template-id* resolves to a *typedef-name*
|
| 1071 |
-
[[temp.names]]
|
|
|
|
| 1072 |
|
| 1073 |
-
[*Note
|
| 1074 |
|
| 1075 |
This implies that, within a class template with a template
|
| 1076 |
*type-parameter* `T`, the declaration
|
| 1077 |
|
| 1078 |
``` cpp
|
|
@@ -1120,23 +1026,23 @@ follows:
|
|
| 1120 |
[[dcl.struct.bind]], `decltype(E)` is the referenced type as given in
|
| 1121 |
the specification of the structured binding declaration;
|
| 1122 |
- otherwise, if E is an unparenthesized *id-expression* naming a
|
| 1123 |
non-type *template-parameter* [[temp.param]], `decltype(E)` is the
|
| 1124 |
type of the *template-parameter* after performing any necessary type
|
| 1125 |
-
deduction
|
| 1126 |
- otherwise, if E is an unparenthesized *id-expression* or an
|
| 1127 |
unparenthesized class member access [[expr.ref]], `decltype(E)` is the
|
| 1128 |
-
type of the entity named by E. If there is no such entity,
|
| 1129 |
-
|
| 1130 |
- otherwise, if E is an xvalue, `decltype(E)` is `T&&`, where `T` is the
|
| 1131 |
type of E;
|
| 1132 |
- otherwise, if E is an lvalue, `decltype(E)` is `T&`, where `T` is the
|
| 1133 |
type of E;
|
| 1134 |
- otherwise, `decltype(E)` is the type of E.
|
| 1135 |
|
| 1136 |
The operand of the `decltype` specifier is an unevaluated operand
|
| 1137 |
-
[[
|
| 1138 |
|
| 1139 |
[*Example 1*:
|
| 1140 |
|
| 1141 |
``` cpp
|
| 1142 |
const int&& foo();
|
|
@@ -1186,11 +1092,11 @@ template<class T> auto f(T) // #1
|
|
| 1186 |
// for the temporary introduced by the use of h().
|
| 1187 |
// (A temporary is not introduced as a result of the use of i().)
|
| 1188 |
template<class T> auto f(T) // #2
|
| 1189 |
-> void;
|
| 1190 |
auto g() -> void {
|
| 1191 |
-
f(42); // OK
|
| 1192 |
// fails[temp.deduct] because A<int>::~A() is implicitly used in its
|
| 1193 |
// decltype-specifier)
|
| 1194 |
}
|
| 1195 |
template<class T> auto q(T)
|
| 1196 |
-> decltype((h<T>())); // does not force completion of A<T>; A<T>::~A() is not implicitly
|
|
@@ -1205,10 +1111,12 @@ void r() {
|
|
| 1205 |
|
| 1206 |
— *end example*]
|
| 1207 |
|
| 1208 |
#### Placeholder type specifiers <a id="dcl.spec.auto">[[dcl.spec.auto]]</a>
|
| 1209 |
|
|
|
|
|
|
|
| 1210 |
``` bnf
|
| 1211 |
placeholder-type-specifier:
|
| 1212 |
type-constraintₒₚₜ auto
|
| 1213 |
type-constraintₒₚₜ decltype '(' auto ')'
|
| 1214 |
```
|
|
@@ -1225,11 +1133,11 @@ placeholder* of the function declaration or *lambda-expression*.
|
|
| 1225 |
|
| 1226 |
[*Note 1*: Having a generic parameter type placeholder signifies that
|
| 1227 |
the function is an abbreviated function template [[dcl.fct]] or the
|
| 1228 |
lambda is a generic lambda [[expr.prim.lambda]]. — *end note*]
|
| 1229 |
|
| 1230 |
-
|
| 1231 |
*decl-specifier-seq*, *type-specifier-seq*, *conversion-function-id*, or
|
| 1232 |
*trailing-return-type*, in any context where such a declarator is valid.
|
| 1233 |
If the function declarator includes a *trailing-return-type*
|
| 1234 |
[[dcl.fct]], that *trailing-return-type* specifies the declared return
|
| 1235 |
type of the function. Otherwise, the function declarator shall declare a
|
|
@@ -1241,54 +1149,49 @@ non-discarded `return` statements, if any, in the body of the function
|
|
| 1241 |
The type of a variable declared using a placeholder type is deduced from
|
| 1242 |
its initializer. This use is allowed in an initializing declaration
|
| 1243 |
[[dcl.init]] of a variable. The placeholder type shall appear as one of
|
| 1244 |
the *decl-specifier*s in the *decl-specifier-seq* and the
|
| 1245 |
*decl-specifier-seq* shall be followed by one or more *declarator*s,
|
| 1246 |
-
each of which shall be followed by a non-empty *initializer*.
|
| 1247 |
-
*initializer* of the form
|
| 1248 |
-
|
| 1249 |
-
``` cpp
|
| 1250 |
-
( expression-list )
|
| 1251 |
-
```
|
| 1252 |
-
|
| 1253 |
-
the *expression-list* shall be a single *assignment-expression*.
|
| 1254 |
|
| 1255 |
[*Example 1*:
|
| 1256 |
|
| 1257 |
``` cpp
|
| 1258 |
-
auto x = 5; // OK
|
| 1259 |
-
const auto *v = &x, u = 6; // OK
|
| 1260 |
-
static auto y = 0.0; // OK
|
| 1261 |
auto int r; // error: auto is not a storage-class-specifier
|
| 1262 |
-
auto f() -> int; // OK
|
| 1263 |
-
auto g() { return 0.0; } // OK
|
| 1264 |
-
auto h(); // OK
|
| 1265 |
```
|
| 1266 |
|
| 1267 |
— *end example*]
|
| 1268 |
|
| 1269 |
The `auto` *type-specifier* can also be used to introduce a structured
|
| 1270 |
binding declaration [[dcl.struct.bind]].
|
| 1271 |
|
| 1272 |
A placeholder type can also be used in the *type-specifier-seq* in the
|
| 1273 |
*new-type-id* or *type-id* of a *new-expression* [[expr.new]] and as a
|
| 1274 |
*decl-specifier* of the *parameter-declaration*'s *decl-specifier-seq*
|
| 1275 |
-
in a *template-parameter* [[temp.param]].
|
|
|
|
|
|
|
| 1276 |
|
| 1277 |
A program that uses a placeholder type in a context not explicitly
|
| 1278 |
-
allowed in
|
| 1279 |
|
| 1280 |
If the *init-declarator-list* contains more than one *init-declarator*,
|
| 1281 |
they shall all form declarations of variables. The type of each declared
|
| 1282 |
variable is determined by placeholder type deduction
|
| 1283 |
[[dcl.type.auto.deduct]], and if the type that replaces the placeholder
|
| 1284 |
type is not the same in each deduction, the program is ill-formed.
|
| 1285 |
|
| 1286 |
[*Example 2*:
|
| 1287 |
|
| 1288 |
``` cpp
|
| 1289 |
-
auto x = 5, *y = &x; // OK
|
| 1290 |
auto a = 5, b = { 1, 2 }; // error: different types for auto
|
| 1291 |
```
|
| 1292 |
|
| 1293 |
— *end example*]
|
| 1294 |
|
|
@@ -1316,15 +1219,15 @@ type shall be defined in the translation unit containing its exported
|
|
| 1316 |
declaration, outside the *private-module-fragment* (if any).
|
| 1317 |
|
| 1318 |
[*Note 2*: The deduced return type cannot have a name with internal
|
| 1319 |
linkage [[basic.link]]. — *end note*]
|
| 1320 |
|
| 1321 |
-
If
|
| 1322 |
-
an expression, the program is ill-formed. Once a
|
| 1323 |
-
statement has been seen in a function, however,
|
| 1324 |
-
from that statement can be used in the rest of
|
| 1325 |
-
in other `return` statements.
|
| 1326 |
|
| 1327 |
[*Example 4*:
|
| 1328 |
|
| 1329 |
``` cpp
|
| 1330 |
auto n = n; // error: n's initializer refers to n
|
|
@@ -1338,14 +1241,14 @@ auto sum(int i) {
|
|
| 1338 |
}
|
| 1339 |
```
|
| 1340 |
|
| 1341 |
— *end example*]
|
| 1342 |
|
| 1343 |
-
Return type deduction for a templated
|
| 1344 |
-
|
| 1345 |
-
|
| 1346 |
-
|
| 1347 |
|
| 1348 |
[*Note 3*: Therefore, any use of a specialization of the function
|
| 1349 |
template will cause an implicit instantiation. Any errors that arise
|
| 1350 |
from this instantiation are not in the immediate context of the function
|
| 1351 |
type and can result in the program being ill-formed
|
|
@@ -1361,24 +1264,22 @@ void g() { int (*p)(int*) = &f; } // instantiates both fs to deter
|
|
| 1361 |
// chooses second
|
| 1362 |
```
|
| 1363 |
|
| 1364 |
— *end example*]
|
| 1365 |
|
| 1366 |
-
|
| 1367 |
-
|
| 1368 |
-
that placeholder, not a deduced type
|
| 1369 |
-
|
| 1370 |
-
return type that does not use a placeholder type shall not use a
|
| 1371 |
-
placeholder.
|
| 1372 |
|
| 1373 |
[*Example 6*:
|
| 1374 |
|
| 1375 |
``` cpp
|
| 1376 |
auto f();
|
| 1377 |
auto f() { return 42; } // return type is int
|
| 1378 |
auto f(); // OK
|
| 1379 |
-
int f(); // error:
|
| 1380 |
decltype(auto) f(); // error: auto and decltype(auto) don't match
|
| 1381 |
|
| 1382 |
template <typename T> auto g(T t) { return t; } // #1
|
| 1383 |
template auto g(int); // OK, return type is int
|
| 1384 |
template char g(char); // error: no matching template
|
|
@@ -1430,44 +1331,63 @@ int (*p)(int) = f; // instantiates f<int> to determine its return t
|
|
| 1430 |
|
| 1431 |
*Placeholder type deduction* is the process by which a type containing a
|
| 1432 |
placeholder type is replaced by a deduced type.
|
| 1433 |
|
| 1434 |
A type `T` containing a placeholder type, and a corresponding
|
| 1435 |
-
initializer E, are determined as follows:
|
| 1436 |
|
| 1437 |
-
-
|
| 1438 |
declared with a return type that contains a placeholder type, `T` is
|
| 1439 |
-
the declared return type
|
| 1440 |
-
|
| 1441 |
-
|
| 1442 |
-
|
| 1443 |
-
|
| 1444 |
-
|
| 1445 |
-
|
| 1446 |
-
|
| 1447 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1448 |
placeholder type, `T` is the declared type of the non-type template
|
| 1449 |
parameter and E is the corresponding template argument.
|
| 1450 |
|
| 1451 |
-
|
| 1452 |
-
of type `void`, `T` shall be either *type-constraint*ₒₚₜ
|
| 1453 |
-
`decltype(auto)` or cv *type-constraint*ₒₚₜ `auto`.
|
| 1454 |
-
|
| 1455 |
-
If the deduction is for a `return` statement and E is a
|
| 1456 |
-
*braced-init-list* [[dcl.init.list]], the program is ill-formed.
|
| 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.
|
| 1461 |
-
|
| 1462 |
-
|
| 1463 |
-
|
| 1464 |
-
|
| 1465 |
-
|
| 1466 |
-
|
| 1467 |
-
|
| 1468 |
-
|
|
|
|
|
|
|
|
|
|
| 1469 |
|
| 1470 |
[*Example 8*:
|
| 1471 |
|
| 1472 |
``` cpp
|
| 1473 |
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
|
|
@@ -1494,12 +1414,12 @@ template <class U> void f(const U& u);
|
|
| 1494 |
|
| 1495 |
— *end example*]
|
| 1496 |
|
| 1497 |
If the *placeholder-type-specifier* is of the form *type-constraint*ₒₚₜ
|
| 1498 |
`decltype(auto)`, `T` shall be the placeholder alone. The type deduced
|
| 1499 |
-
for `T` is determined as described in [[dcl.type.
|
| 1500 |
-
had been the operand of the `decltype`.
|
| 1501 |
|
| 1502 |
[*Example 10*:
|
| 1503 |
|
| 1504 |
``` cpp
|
| 1505 |
int i;
|
|
@@ -1514,10 +1434,12 @@ auto x5a = f(); // decltype(x5a) is int
|
|
| 1514 |
decltype(auto) x5d = f(); // decltype(x5d) is int&&
|
| 1515 |
auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
|
| 1516 |
decltype(auto) x6d = { 1, 2 }; // error: { 1, 2 } is not an expression
|
| 1517 |
auto *x7a = &i; // decltype(x7a) is int*
|
| 1518 |
decltype(auto)*x7d = &i; // error: declared type is not plain decltype(auto)
|
|
|
|
|
|
|
| 1519 |
```
|
| 1520 |
|
| 1521 |
— *end example*]
|
| 1522 |
|
| 1523 |
For a *placeholder-type-specifier* with a *type-constraint*, the
|
|
|
|
| 1 |
## Specifiers <a id="dcl.spec">[[dcl.spec]]</a>
|
| 2 |
|
| 3 |
+
### General <a id="dcl.spec.general">[[dcl.spec.general]]</a>
|
| 4 |
+
|
| 5 |
The specifiers that can be used in a declaration are
|
| 6 |
|
| 7 |
``` bnf
|
| 8 |
decl-specifier:
|
| 9 |
storage-class-specifier
|
|
|
|
| 95 |
`static` or `extern`. If `thread_local` appears in any declaration of a
|
| 96 |
variable it shall be present in all declarations of that entity. If a
|
| 97 |
*storage-class-specifier* appears in a *decl-specifier-seq*, there can
|
| 98 |
be no `typedef` specifier in the same *decl-specifier-seq* and the
|
| 99 |
*init-declarator-list* or *member-declarator-list* of the declaration
|
| 100 |
+
shall not be empty (except for an anonymous union declared in a
|
| 101 |
+
namespace scope [[class.union.anon]]). The *storage-class-specifier*
|
| 102 |
+
applies to the name declared by each *init-declarator* in the list and
|
| 103 |
+
not to any names declared by other specifiers.
|
|
|
|
| 104 |
|
| 105 |
[*Note 1*: See [[temp.expl.spec]] and [[temp.explicit]] for
|
| 106 |
restrictions in explicit specializations and explicit instantiations,
|
| 107 |
respectively. — *end note*]
|
| 108 |
|
|
|
|
| 138 |
|
| 139 |
[*Note 3*: The `extern` keyword can also be used in
|
| 140 |
*explicit-instantiation*s and *linkage-specification*s, but it is not a
|
| 141 |
*storage-class-specifier* in such contexts. — *end note*]
|
| 142 |
|
| 143 |
+
All declarations for a given entity shall give its name the same
|
| 144 |
+
linkage.
|
| 145 |
+
|
| 146 |
+
[*Note 4*: The linkage given by some declarations is affected by
|
| 147 |
+
previous declarations. Overloads are distinct entities. — *end note*]
|
| 148 |
|
| 149 |
[*Example 1*:
|
| 150 |
|
| 151 |
``` cpp
|
| 152 |
static char* f(); // f() has internal linkage
|
|
|
|
| 217 |
};
|
| 218 |
```
|
| 219 |
|
| 220 |
— *end example*]
|
| 221 |
|
| 222 |
+
[*Note 5*: The `mutable` specifier on a class data member nullifies a
|
| 223 |
`const` specifier applied to the containing class object and permits
|
| 224 |
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 |
|
|
|
|
| 240 |
explicit '(' constant-expression ')'
|
| 241 |
explicit
|
| 242 |
```
|
| 243 |
|
| 244 |
The `virtual` specifier shall be used only in the initial declaration of
|
| 245 |
+
a non-static member function; see [[class.virtual]].
|
| 246 |
|
| 247 |
An *explicit-specifier* shall be used only in the declaration of a
|
| 248 |
constructor or conversion function within its class definition; see
|
| 249 |
[[class.conv.ctor]] and [[class.conv.fct]].
|
| 250 |
|
|
|
|
| 255 |
`explicit(true)`. If the constant expression evaluates to `true`, the
|
| 256 |
function is explicit. Otherwise, the function is not explicit. A `(`
|
| 257 |
token that follows `explicit` is parsed as part of the
|
| 258 |
*explicit-specifier*.
|
| 259 |
|
| 260 |
+
[*Example 1*:
|
| 261 |
+
|
| 262 |
+
``` cpp
|
| 263 |
+
struct S {
|
| 264 |
+
explicit(sizeof(char[2])) S(char); // error: narrowing conversion of value 2 to type bool
|
| 265 |
+
explicit(sizeof(char)) S(bool); // OK, conversion of value 1 to type bool is non-narrowing
|
| 266 |
+
};
|
| 267 |
+
```
|
| 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 |
identifiers that can be used later for naming fundamental
|
| 275 |
[[basic.fundamental]] or compound [[basic.compound]] types. The
|
|
|
|
| 312 |
of `metricp` is “pointer to `int`”.
|
| 313 |
|
| 314 |
— *end example*]
|
| 315 |
|
| 316 |
A *typedef-name* can also be introduced by an *alias-declaration*. The
|
| 317 |
+
*identifier* following the `using` keyword is not looked up; it becomes
|
| 318 |
+
a *typedef-name* and the optional *attribute-specifier-seq* following
|
| 319 |
+
the *identifier* appertains to that *typedef-name*. Such a
|
| 320 |
+
*typedef-name* has the same semantics as if it were introduced by the
|
| 321 |
+
`typedef` specifier. In particular, it does not define a new type.
|
| 322 |
|
| 323 |
[*Example 2*:
|
| 324 |
|
| 325 |
``` cpp
|
| 326 |
using handler_t = void (*)(int);
|
| 327 |
extern handler_t ignore;
|
| 328 |
extern void (*ignore)(int); // redeclare ignore
|
| 329 |
+
template<class T> struct P { };
|
| 330 |
+
using cell = P<cell*>; // error: cell not found[basic.scope.pdecl]
|
| 331 |
```
|
| 332 |
|
| 333 |
— *end example*]
|
| 334 |
|
| 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 *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
|
| 346 |
declaration [[class.ctor]], or a destructor declaration [[class.dtor]],
|
| 347 |
the program is ill-formed. — *end note*]
|
| 348 |
|
| 349 |
+
[*Example 3*:
|
| 350 |
|
| 351 |
``` cpp
|
| 352 |
struct S {
|
| 353 |
S();
|
| 354 |
~S();
|
|
|
|
| 360 |
struct T * p; // error
|
| 361 |
```
|
| 362 |
|
| 363 |
— *end example*]
|
| 364 |
|
| 365 |
+
An unnamed class or enumeration C defined in a typedef declaration has
|
| 366 |
+
the first *typedef-name* declared by the declaration to be of type C as
|
| 367 |
+
its *typedef name for linkage purposes* [[basic.link]].
|
| 368 |
|
| 369 |
[*Note 2*: A typedef declaration involving a *lambda-expression* does
|
| 370 |
not itself define the associated closure type, and so the closure type
|
| 371 |
+
is not given a typedef name for linkage purposes. — *end note*]
|
| 372 |
|
| 373 |
+
[*Example 4*:
|
| 374 |
|
| 375 |
``` cpp
|
| 376 |
+
typedef struct { } *ps, S; // S is the typedef name for linkage purposes
|
| 377 |
+
typedef decltype([]{}) C; // the closure type has no typedef name for linkage purposes
|
| 378 |
```
|
| 379 |
|
| 380 |
— *end example*]
|
| 381 |
|
| 382 |
An unnamed class with a typedef name for linkage purposes shall not
|
|
|
|
| 387 |
- contain a *lambda-expression*,
|
| 388 |
|
| 389 |
and all member classes shall also satisfy these requirements
|
| 390 |
(recursively).
|
| 391 |
|
| 392 |
+
[*Example 5*:
|
| 393 |
|
| 394 |
``` cpp
|
| 395 |
typedef struct {
|
| 396 |
int f() {}
|
| 397 |
} X; // error: struct with typedef name for linkage has member functions
|
|
|
|
| 424 |
`constexpr`. — *end note*]
|
| 425 |
|
| 426 |
[*Example 1*:
|
| 427 |
|
| 428 |
``` cpp
|
| 429 |
+
constexpr void square(int &x); // OK, declaration
|
| 430 |
+
constexpr int bufsz = 1024; // OK, definition
|
| 431 |
constexpr struct pixel { // error: pixel is a type
|
| 432 |
int x;
|
| 433 |
int y;
|
| 434 |
+
constexpr pixel(int); // OK, declaration
|
| 435 |
};
|
| 436 |
constexpr pixel::pixel(int a)
|
| 437 |
+
: x(a), y(x) // OK, definition
|
| 438 |
{ square(x); }
|
| 439 |
constexpr pixel small(2); // error: square not defined, so small(2)
|
| 440 |
// not constant[expr.const] so constexpr not satisfied
|
| 441 |
|
| 442 |
+
constexpr void square(int &x) { // OK, definition
|
| 443 |
x *= x;
|
| 444 |
}
|
| 445 |
+
constexpr pixel large(4); // OK, square defined
|
| 446 |
int next(constexpr int x) { // error: not for parameters
|
| 447 |
return x + 1;
|
| 448 |
}
|
| 449 |
extern constexpr int memsz; // error: not a definition
|
| 450 |
```
|
| 451 |
|
| 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 or constructor declared with the `consteval`
|
| 458 |
+
specifier is an immediate function [[expr.const]]. — *end note*]
|
| 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*:
|
| 473 |
|
| 474 |
``` cpp
|
| 475 |
constexpr int square(int x)
|
|
|
|
| 479 |
constexpr int abs(int x) {
|
| 480 |
if (x < 0)
|
| 481 |
x = -x;
|
| 482 |
return x; // OK
|
| 483 |
}
|
| 484 |
+
constexpr int constant_non_42(int n) { // OK
|
| 485 |
+
if (n == 42) {
|
| 486 |
+
static int value = n;
|
| 487 |
return value;
|
| 488 |
}
|
| 489 |
+
return n;
|
| 490 |
+
}
|
| 491 |
constexpr int uninit() {
|
| 492 |
struct { int a; } s;
|
| 493 |
return s.a; // error: uninitialized read of s.a
|
| 494 |
}
|
| 495 |
constexpr int prev(int x)
|
|
|
|
| 501 |
}
|
| 502 |
```
|
| 503 |
|
| 504 |
— *end example*]
|
| 505 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 506 |
An invocation of a constexpr function in a given context produces the
|
| 507 |
same result as an invocation of an equivalent non-constexpr function in
|
| 508 |
the same context in all respects except that
|
| 509 |
|
| 510 |
- an invocation of a constexpr function can appear in a constant
|
|
|
|
| 515 |
[*Note 4*: Declaring a function constexpr can change whether an
|
| 516 |
expression is a constant expression. This can indirectly cause calls to
|
| 517 |
`std::is_constant_evaluated` within an invocation of the function to
|
| 518 |
produce a different value. — *end note*]
|
| 519 |
|
| 520 |
+
[*Note 5*: It is possible to write a constexpr function for which no
|
| 521 |
+
invocation satisfies the requirements of a core constant
|
| 522 |
+
expression. — *end note*]
|
| 523 |
+
|
| 524 |
The `constexpr` and `consteval` specifiers have no effect on the type of
|
| 525 |
a constexpr function.
|
| 526 |
|
| 527 |
+
[*Example 3*:
|
| 528 |
|
| 529 |
``` cpp
|
| 530 |
constexpr int bar(int x, int y) // OK
|
| 531 |
{ return x + y + x*y; }
|
| 532 |
// ...
|
|
|
|
| 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. In any `constexpr` variable declaration, the
|
| 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*:
|
| 548 |
|
| 549 |
``` cpp
|
| 550 |
struct pixel {
|
| 551 |
int x, y;
|
| 552 |
};
|
|
|
|
| 563 |
applied to any declaration of a variable, it shall be applied to the
|
| 564 |
initializing declaration. No diagnostic is required if no `constinit`
|
| 565 |
declaration is reachable at the point of the initializing declaration.
|
| 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 1*: The `constinit` specifier ensures that the variable is
|
| 573 |
+
initialized during static initialization. — *end note*]
|
|
|
|
| 574 |
|
| 575 |
[*Example 1*:
|
| 576 |
|
| 577 |
``` cpp
|
| 578 |
const char * g() { return "dynamic initialization"; }
|
|
|
|
| 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 |
variable or function.
|
| 590 |
|
| 591 |
+
A function declaration [[dcl.fct]], [[class.mfct]], [[class.friend]]
|
| 592 |
with an `inline` specifier declares an *inline function*. The inline
|
| 593 |
specifier indicates to the implementation that inline substitution of
|
| 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
|
|
|
|
| 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 2*: A call to an inline function or a use of an inline variable
|
| 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
|
| 634 |
+
implicitly inline [[class.mfct]], [[class.friend]]. — *end note*]
|
| 635 |
|
| 636 |
### Type specifiers <a id="dcl.type">[[dcl.type]]</a>
|
| 637 |
|
| 638 |
+
#### General <a id="dcl.type.general">[[dcl.type.general]]</a>
|
| 639 |
+
|
| 640 |
The type-specifiers are
|
| 641 |
|
| 642 |
``` bnf
|
| 643 |
type-specifier:
|
| 644 |
simple-type-specifier
|
|
|
|
| 693 |
complete *decl-specifier-seq*.[^1]
|
| 694 |
|
| 695 |
[*Note 1*: *enum-specifier*s, *class-specifier*s, and
|
| 696 |
*typename-specifier*s are discussed in [[dcl.enum]], [[class]], and
|
| 697 |
[[temp.res]], respectively. The remaining *type-specifier*s are
|
| 698 |
+
discussed in the rest of [[dcl.type]]. — *end note*]
|
| 699 |
|
| 700 |
#### The *cv-qualifier*s <a id="dcl.type.cv">[[dcl.type.cv]]</a>
|
| 701 |
|
| 702 |
There are two *cv-qualifier*s, `const` and `volatile`. Each
|
| 703 |
*cv-qualifier* shall appear at most once in a *cv-qualifier-seq*. If a
|
|
|
|
| 726 |
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.ass]], [[expr.post.incr]], [[expr.pre.incr]] a const object
|
| 733 |
+
[[basic.type.qualifier]] during its lifetime [[basic.life]] results in
|
| 734 |
+
undefined behavior.
|
| 735 |
|
| 736 |
[*Example 1*:
|
| 737 |
|
| 738 |
``` cpp
|
| 739 |
const int ci = 3; // cv-qualified (initialized as required)
|
| 740 |
ci = 4; // error: attempt to modify const
|
| 741 |
|
| 742 |
int i = 2; // not cv-qualified
|
| 743 |
const int* cip; // pointer to const int
|
| 744 |
+
cip = &i; // OK, cv-qualified access path to unqualified
|
| 745 |
*cip = 4; // error: attempt to modify through ptr to const
|
| 746 |
|
| 747 |
int* ip;
|
| 748 |
ip = const_cast<int*>(cip); // cast needed to convert const int* to int*
|
| 749 |
*ip = 4; // defined: *ip points to i, a non-const object
|
|
|
|
| 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* of the form `typename`ₒₚₜ
|
| 834 |
*nested-name-specifier*ₒₚₜ *template-name* is a placeholder for a
|
| 835 |
deduced class type [[dcl.type.class.deduct]]. The
|
| 836 |
*nested-name-specifier*, if any, shall be non-dependent and the
|
|
|
|
| 913 |
``` bnf
|
| 914 |
elaborated-type-specifier:
|
| 915 |
class-key attribute-specifier-seqₒₚₜ nested-name-specifierₒₚₜ identifier
|
| 916 |
class-key simple-template-id
|
| 917 |
class-key nested-name-specifier templateₒₚₜ simple-template-id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 918 |
enum nested-name-specifierₒₚₜ identifier
|
| 919 |
```
|
| 920 |
|
| 921 |
+
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]], an explicit instantiation
|
| 928 |
[[temp.explicit]] or it has one of the following forms:
|
| 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 |
+
[[temp.decls]]). The *attribute-specifier-seq*, if any, appertains to
|
| 940 |
+
the class or template being declared.
|
| 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 |
+
If an *elaborated-type-specifier* appears with the `friend` specifier as
|
| 950 |
+
an entire *member-declaration*, the *member-declaration* shall have one
|
| 951 |
+
of the following forms:
|
| 952 |
+
|
| 953 |
+
``` bnf
|
| 954 |
+
friend class-key nested-name-specifierₒₚₜ identifier ';'
|
| 955 |
+
friend class-key simple-template-id ';'
|
| 956 |
friend class-key nested-name-specifier templateₒₚₜ simple-template-id ';'
|
| 957 |
```
|
| 958 |
|
| 959 |
+
Any unqualified lookup for the *identifier* (in the first case) does not
|
| 960 |
+
consider scopes that contain the target scope; no name is bound.
|
|
|
|
|
|
|
| 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. [[basic.lookup.elab]]
|
| 964 |
+
describes how name lookup proceeds in an
|
| 965 |
+
*elaborated-type-specifier*. — *end note*]
|
| 966 |
+
|
| 967 |
+
[*Note 2*: An *elaborated-type-specifier* can be used to refer to a
|
| 968 |
+
previously declared *class-name* or *enum-name* even if the name has
|
| 969 |
+
been hidden by a non-type declaration. — *end note*]
|
| 970 |
|
| 971 |
If the *identifier* or *simple-template-id* resolves to a *class-name*
|
| 972 |
or *enum-name*, the *elaborated-type-specifier* introduces it into the
|
| 973 |
declaration the same way a *simple-type-specifier* introduces its
|
| 974 |
*type-name* [[dcl.type.simple]]. If the *identifier* or
|
| 975 |
+
*simple-template-id* resolves to a *typedef-name*
|
| 976 |
+
[[dcl.typedef]], [[temp.names]], the *elaborated-type-specifier* is
|
| 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
|
|
|
|
| 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 |
non-type *template-parameter* [[temp.param]], `decltype(E)` is the
|
| 1030 |
type of the *template-parameter* after performing any necessary type
|
| 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.
|
| 1041 |
|
| 1042 |
The operand of the `decltype` specifier is an unevaluated operand
|
| 1043 |
+
[[term.unevaluated.operand]].
|
| 1044 |
|
| 1045 |
[*Example 1*:
|
| 1046 |
|
| 1047 |
``` cpp
|
| 1048 |
const int&& foo();
|
|
|
|
| 1092 |
// for the temporary introduced by the use of h().
|
| 1093 |
// (A temporary is not introduced as a result of the use of i().)
|
| 1094 |
template<class T> auto f(T) // #2
|
| 1095 |
-> void;
|
| 1096 |
auto g() -> void {
|
| 1097 |
+
f(42); // OK, calls #2. (#1 is not a viable candidate: type deduction
|
| 1098 |
// fails[temp.deduct] because A<int>::~A() is implicitly used in its
|
| 1099 |
// decltype-specifier)
|
| 1100 |
}
|
| 1101 |
template<class T> auto q(T)
|
| 1102 |
-> decltype((h<T>())); // does not force completion of A<T>; A<T>::~A() is not implicitly
|
|
|
|
| 1111 |
|
| 1112 |
— *end example*]
|
| 1113 |
|
| 1114 |
#### Placeholder type specifiers <a id="dcl.spec.auto">[[dcl.spec.auto]]</a>
|
| 1115 |
|
| 1116 |
+
##### General <a id="dcl.spec.auto.general">[[dcl.spec.auto.general]]</a>
|
| 1117 |
+
|
| 1118 |
``` bnf
|
| 1119 |
placeholder-type-specifier:
|
| 1120 |
type-constraintₒₚₜ auto
|
| 1121 |
type-constraintₒₚₜ decltype '(' auto ')'
|
| 1122 |
```
|
|
|
|
| 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 with a function declarator in the
|
| 1139 |
*decl-specifier-seq*, *type-specifier-seq*, *conversion-function-id*, or
|
| 1140 |
*trailing-return-type*, in any context where such a declarator is valid.
|
| 1141 |
If the function declarator includes a *trailing-return-type*
|
| 1142 |
[[dcl.fct]], that *trailing-return-type* specifies the declared return
|
| 1143 |
type of the function. Otherwise, the function declarator shall declare a
|
|
|
|
| 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* and the
|
| 1153 |
*decl-specifier-seq* shall be followed by one or more *declarator*s,
|
| 1154 |
+
each of which shall be followed by a non-empty *initializer*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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* in the
|
| 1174 |
*new-type-id* or *type-id* of a *new-expression* [[expr.new]] and as a
|
| 1175 |
*decl-specifier* of the *parameter-declaration*'s *decl-specifier-seq*
|
| 1176 |
+
in a *template-parameter* [[temp.param]]. The `auto` *type-specifier*
|
| 1177 |
+
can also be used as the *simple-type-specifier* in an explicit type
|
| 1178 |
+
conversion (functional notation) [[expr.type.conv]].
|
| 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*,
|
| 1184 |
they shall all form declarations of variables. The type of each declared
|
| 1185 |
variable is determined by placeholder type deduction
|
| 1186 |
[[dcl.type.auto.deduct]], and if the type that replaces the placeholder
|
| 1187 |
type is not the same in each deduction, the program is ill-formed.
|
| 1188 |
|
| 1189 |
[*Example 2*:
|
| 1190 |
|
| 1191 |
``` cpp
|
| 1192 |
+
auto x = 5, *y = &x; // OK, auto is int
|
| 1193 |
auto a = 5, b = { 1, 2 }; // error: different types for auto
|
| 1194 |
```
|
| 1195 |
|
| 1196 |
— *end example*]
|
| 1197 |
|
|
|
|
| 1219 |
declaration, outside the *private-module-fragment* (if any).
|
| 1220 |
|
| 1221 |
[*Note 2*: The deduced return type cannot have a name with internal
|
| 1222 |
linkage [[basic.link]]. — *end note*]
|
| 1223 |
|
| 1224 |
+
If a variable or function with an undeduced placeholder type is named by
|
| 1225 |
+
an expression [[basic.def.odr]], the program is ill-formed. Once a
|
| 1226 |
+
non-discarded `return` statement has been seen in a function, however,
|
| 1227 |
+
the return type deduced from that statement can be used in the rest of
|
| 1228 |
+
the function, including in other `return` statements.
|
| 1229 |
|
| 1230 |
[*Example 4*:
|
| 1231 |
|
| 1232 |
``` cpp
|
| 1233 |
auto n = n; // error: n's initializer refers to n
|
|
|
|
| 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 |
|
| 1251 |
[*Note 3*: Therefore, any use of a specialization of the function
|
| 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
|
|
|
|
| 1264 |
// chooses second
|
| 1265 |
```
|
| 1266 |
|
| 1267 |
— *end example*]
|
| 1268 |
|
| 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 6*:
|
| 1275 |
|
| 1276 |
``` cpp
|
| 1277 |
auto f();
|
| 1278 |
auto f() { return 42; } // return type is int
|
| 1279 |
auto f(); // OK
|
| 1280 |
+
int f(); // error: auto and int don't match
|
| 1281 |
decltype(auto) f(); // error: auto and decltype(auto) don't match
|
| 1282 |
|
| 1283 |
template <typename T> auto g(T t) { return t; } // #1
|
| 1284 |
template auto g(int); // OK, return type is int
|
| 1285 |
template char g(char); // error: no matching template
|
|
|
|
| 1331 |
|
| 1332 |
*Placeholder type deduction* is the process by which a type containing a
|
| 1333 |
placeholder type is replaced by a deduced type.
|
| 1334 |
|
| 1335 |
A type `T` containing a placeholder type, and a corresponding
|
| 1336 |
+
*initializer-clause* E, are determined as follows:
|
| 1337 |
|
| 1338 |
+
- For a non-discarded `return` statement that occurs in a function
|
| 1339 |
declared with a return type that contains a placeholder type, `T` is
|
| 1340 |
+
the declared return type.
|
| 1341 |
+
- If the `return` statement has no operand, then E is `void()`.
|
| 1342 |
+
- If the operand is a *braced-init-list* [[dcl.init.list]], the
|
| 1343 |
+
program is ill-formed.
|
| 1344 |
+
- If the operand is an *expression* X that is not an
|
| 1345 |
+
*assignment-expression*, E is `(X)`. \[*Note 4*: A comma expression
|
| 1346 |
+
[[expr.comma]] is not an *assignment-expression*. — *end note*]
|
| 1347 |
+
- Otherwise, E is the operand of the `return` statement.
|
| 1348 |
+
|
| 1349 |
+
If E has type `void`, `T` shall be either *type-constraint*ₒₚₜ
|
| 1350 |
+
`decltype(auto)` or cv *type-constraint*ₒₚₜ `auto`.
|
| 1351 |
+
- For a variable declared with a type that contains a placeholder type,
|
| 1352 |
+
`T` is the declared type of the variable.
|
| 1353 |
+
- If the initializer of the variable is a *brace-or-equal-initializer*
|
| 1354 |
+
of the form `= initializer-clause`, E is the *initializer-clause*.
|
| 1355 |
+
- If the initializer is a *braced-init-list*, it shall consist of a
|
| 1356 |
+
single brace-enclosed *assignment-expression* and E is the
|
| 1357 |
+
*assignment-expression*.
|
| 1358 |
+
- If the initializer is a parenthesized *expression-list*, the
|
| 1359 |
+
*expression-list* shall be a single *assignment-expression* and E is
|
| 1360 |
+
the *assignment-expression*.
|
| 1361 |
+
- For an explicit type conversion [[expr.type.conv]], `T` is the
|
| 1362 |
+
specified type, which shall be `auto`.
|
| 1363 |
+
- If the initializer is a *braced-init-list*, it shall consist of a
|
| 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 non-type template parameter declared with a type that contains a
|
| 1370 |
placeholder type, `T` is the declared type of the non-type template
|
| 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 occurrences of
|
| 1381 |
+
*type-constraint*ₒₚₜ `auto` either with a new invented type template
|
| 1382 |
+
parameter `U` or, if the initialization is copy-list-initialization,
|
| 1383 |
+
with `std::initializer_list<U>`. Deduce a value for `U` using the rules
|
| 1384 |
+
of template argument deduction from a function call
|
| 1385 |
+
[[temp.deduct.call]], where `P` is a function template parameter type
|
| 1386 |
+
and the corresponding argument is E. If the deduction fails, the
|
| 1387 |
+
declaration is ill-formed. Otherwise, T' is obtained by substituting the
|
| 1388 |
+
deduced `U` into `P`.
|
| 1389 |
|
| 1390 |
[*Example 8*:
|
| 1391 |
|
| 1392 |
``` cpp
|
| 1393 |
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
|
|
|
|
| 1414 |
|
| 1415 |
— *end example*]
|
| 1416 |
|
| 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 10*:
|
| 1423 |
|
| 1424 |
``` cpp
|
| 1425 |
int i;
|
|
|
|
| 1434 |
decltype(auto) x5d = f(); // decltype(x5d) is int&&
|
| 1435 |
auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
|
| 1436 |
decltype(auto) x6d = { 1, 2 }; // error: { 1, 2 } is not an expression
|
| 1437 |
auto *x7a = &i; // decltype(x7a) is int*
|
| 1438 |
decltype(auto)*x7d = &i; // error: declared type is not plain decltype(auto)
|
| 1439 |
+
auto f1(int x) -> decltype((x)) { return (x); } // return type is int&
|
| 1440 |
+
auto f2(int x) -> decltype(auto) { return (x); } // return type is int&&
|
| 1441 |
```
|
| 1442 |
|
| 1443 |
— *end example*]
|
| 1444 |
|
| 1445 |
For a *placeholder-type-specifier* with a *type-constraint*, the
|