Created on 2016-08-12.00:00:00 last changed 28 months ago
Proposed resolution (August, 2017):
Change 11.5 [dcl.struct.bind] paragraph 3 as follows:
Otherwise, if the qualified-id std::tuple_size<E> names a complete type, the expression std::tuple_size<E>::value shall be a well-formed integral constant expression and the number of elements in the identifier-list shall be equal to the value of that expression. The unqualified-id get is looked up in the scope of E by class member access lookup (6.4.5 [basic.lookup.classref]), and if that finds at least one declaration, the initializer is e.get<i>(). Otherwise, the initializer is get<i>(e) where get is looked up in the associated namespaces (6.4.2 [basic.lookup.argdep]). In either case, get<i> is interpreted as a template-id. [Note: Ordinary unqualified lookup (6.4.1 [basic.lookup.unqual]) is not performed. —end note] In either case, e is an lvalue if the type of the entity e is an lvalue reference and an xvalue otherwise. Given the type Ti designated by std::tuple_element<i, E>::type ,
each vi is a variableof 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.
[Accepted as a DR at the November, 2017 meeting.]
According to the current rules for structured binding declarations, the user-defined case declares the bindings as variables of reference type. This presumably makes an example like the following valid:
auto [a] = std::tuple<int>(0); extern int &&a; // ok, redeclaration, could even be in a different TU
This seems unreasonable, especially in light of the fact that it only works for the user-defined case and not the built-in case (where the bindings are not modeled as references).
|2018-02-27 00:00:00||admin||set||messages: + msg6116|