... The type of the expression is the type of the identifier. The result is the entity denoted by the identifier. The result is the entity denoted by the identifier. The result is an lvalue if the entity is a function, variable, or data member and a prvalue otherwise. The result is a bit-field if the identifier designates a bit-field (7.1.6.4 [dcl.spec.auto]).Change in 5.2.5 [expr.ref] paragraph 3:
Abbreviating postfix-expression.id-expressionx 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:E2is a bit-field,E1.E2is a bit-field. ...
for-range-declaration:
attribute-specifier-seqopt decl-specifier-seq declarator
attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ]
In section 7 [dcl.dcl] paragraph 1, change the grammar to allow a
decomposition declaration:
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 ;
Add a new paragraph after 7 [dcl.dcl] paragraph 8:
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 after 7.1.6.4 [dcl.spec.auto] paragraph 8: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.
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,ehas type cvAand is copy-initialized or direct-initialized from the assignment-expression as specified by the form of the brace-or-equal-initializer. Otherwise,eis 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 expressioneis calledE. [ Note:Eis never a reference type (Clause 5 [expr]). -- end note ]If
Eis 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 ]Otherwise, if the expression
std::tuple_size<E>::valueis 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-idgetis looked up in the scope ofEby 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), wheregetis looked up in the associated namespaces (3.4.2 [basic.lookup.argdep]). [ Note: Ordinary unqualified lookup (3.4.1 [basic.lookup.unqual]) is not performed. -- end note ] In either case,eis an lvalue if the type of the entityeis 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 and bit-fields shall be public direct members ofEor of the same unambiguous public base class ofE,Eshall 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 ofeand 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 x; volatile double y; }; S f(); const auto [ x, y ] = f();The type of the expressionxis "const int", the type of the expressionyis "const volatile double". -- end example ]