... The type of the expression is the type of the identifier. The result is the entity denoted by the identifier. TheChange in 5.1.5 [expr.prim.lambda] paragraph 18:resultexpression is an lvalue if the entity is a function, variable, or data member and a prvalue otherwise; it is a bit-field if the identifier designates a bit-field (7.1.6.4 [dcl.spec.auto]).
... A bit-field or a member of an anonymous union shall not be captured by reference.Change in 5.2.5 [expr.ref] paragraph 3:
Abbreviating postfix-expression.id-expression as E1.E2, E1 is called the object expression. IfIn section 6.5 [stmt.iter] paragraph 1, change the grammar to allow a decomposition declaration:E2
is a bit-field,E1.E2
is a bit-field. ...
In section 7 [dcl.dcl] paragraph 1, change the grammar to allow a decomposition declaration:for-range-declaration: attribute-specifier-seqopt decl-specifier-seq declarator attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ]
Add a new paragraph after 7 [dcl.dcl] paragraph 8:simple-declaration: decl-specifier-seq init-declarator-listopt ; attribute-specifier-seq decl-specifier-seq init-declarator-list ; attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ] brace-or-equal-initializer ;
A simple-declaration with an identifier-list is
called a decomposition declaration. The
decl-specifier-seq shall contain only the
type-specifier auto
(7.1.6.4 [dcl.spec.auto])
and cv-qualifiers. The brace-or-equal-initializer
shall be of the form "= assignment-expression" or of the form
"{ assignment-expression }", where the
assignment-expression is of array or non-union class
type.
Change in 7.1.6.2 [dcl.type.simple] paragraph 4:
For an expression e, the type denoted byAdd in 7.1.6.4 [dcl.spec.auto] paragraph 1:decltype(e)
is defined as follows:
- if e is an unparenthesized id-expression naming an lvalue or reference introduced from the identifier-list of a decomposition declaration,
decltype(e)
is the referenced type as given in the specification of the decomposition declaration (7.1.6.4 [dcl.spec.auto]);- otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
- otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;
- otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
- otherwise, decltype(e) is the type of e.
TheAdd a new section before 8.5 [dcl.init]:auto
anddecltype(auto)
type-specifiers are used to designate a placeholder type that will be replaced later by deduction from an initializer. The auto type-specifier is also used to introduce a function type having a trailing-return-type or to signify that a lambda is a generic lambda (5.1.5 [expr.prim.lambda]). Theauto
type-specifier is also used to introduce a decomposition declaration (8.5 [dcl.decomp]).
8.5 Decomposition declarations [dcl.decomp]Add in 14.6.2.2 [temp.dep.expr] paragraph 3:A decomposition declaration introduces the identifiers of the identifier-list as names in the order of appearance, where vi denotes the i-th identifier, with numbering starting at 1. Let cv denote the cv-qualifiers in the decl-specifier-seq. First, a variable with a unique name e is introduced. If the assignment-expression in the brace-or-equal-initializer has array type A and no ref-qualifier is present,
e
has type cvA
and each element is copy-initialized or direct-initialized from the corresponding element of the assignment-expression as specified by the form of the brace-or-equal-initializer. Otherwise,e
is defined as-if byattribute-specifier-seqopt decl-specifier-seq ref-qualifieropt e brace-or-equal-initializer ;where the parts of the declaration other than the declarator-id are taken from the corresponding decomposition declaration. The type of the id-expressione
is calledE
. [ Note:E
is never a reference type (Clause 5 [expr]). -- end note ]If
E
is an array type with element type T, the number of elements in the identifier-list shall be equal to the number of elements ofE
. Each vi is the name of an lvalue that refers to the element i-1 of the array and whose type is T; the referenced type is T. [ Note: The top-level cv-qualifiers of T are cv. -- end note ] [ Example:auto f() -> int(&)[2]; auto [ x, y ] = f(); // x and y refer to elements in a copy of the array return value auto& [ xr, yr ] = f(); // xr and yr refer to elements in the array referred to by f's return value-- end example ]Otherwise, if the expression
std::tuple_size<E>::value
is a well-formed integral constant expression, the number of elements in the identifier-list shall be equal to the value of that expression. The unqualified-idget
is looked up in the scope ofE
by class member access lookup (3.4.5 [basic.lookup.classref]), and if that finds at least one declaration, the initializer ise.get<i-1>()
. Otherwise, the initializer isget<i-1>(e)
, whereget
is looked up in the associated namespaces (3.4.2 [basic.lookup.argdep]). In either case,get<i-1>
is taken as a template-id. [ Note: Ordinary unqualified lookup (3.4.1 [basic.lookup.unqual]) is not performed. -- end note ] In either case,e
is an lvalue if the type of the entitye
is an lvalue reference and an xvalue otherwise. Given the type Ti designated bystd::tuple_element<i-1,E>::type
, each vi is a variable of type "reference to Ti" initialized with the initializer, where the reference is an lvalue reference if the initializer is an lvalue and an rvalue reference otherwise; the referenced type is Ti.Otherwise, all of
E
's non-static data members shall be public direct members ofE
or of the same unambiguous public base class ofE
,E
shall not have an anonymous union member, and the number of elements in the identifier-list shall be equal to the number of non-static data members ofE
. The i-th non-static data member of E in declaration order is designated by mi. Each vi is the name of an lvalue that refers to the member mi ofe
and whose type is cv Ti, where Ti is the declared type of that member; the referenced type is cv Ti. The lvalue is a bit-field if that member is a bit-field. [ Example:struct S { int x1 : 2; volatile double y1; }; S f(); const auto [ x, y ] = f();The type of the id-expressionx
is "const int", the type of the id-expressiony
is "const volatile double". -- end example ]
An id-expression is type-dependent if it contains
- ...
- an identifier associated by name lookup with a decomposition declaration (8.5 [dcl.decomp]) whose brace-or-equal-initializer is type-dependent,
- ...