CWG Issue 2313 (original) (raw)

This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 117a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-04-13


2313. Redeclaration of structured binding reference variables

Section: 9.7 [dcl.struct.bind]Status: CD5Submitter: Richard SmithDate: 2016-08-12

[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(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).

Proposed resolution (August, 2017):

Change 9.7 [dcl.struct.bind] paragraph 3 as follows:

Otherwise, if the qualified-id std::tuple_sizenames a complete type, the expression std::tuple_size::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 (_N4868_.6.5.6 [basic.lookup.classref]), and if that finds at least one declaration, the initializer is e.get(). Otherwise, the initializer is get(e) where get is looked up in the associated namespaces (6.5.4 [basic.lookup.argdep]). In either case,get is interpreted as a template-id. [Note:_Ordinary unqualified lookup (6.5.3 [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 T_i designated by std::tuple_element<i, E>::type ,each v_i_ is a variable variables are introduced with unique names r_i_ of type “reference to T_i_ ” initialized with the initializer(9.5.4 [dcl.init.ref]), where the reference is an lvalue reference if the initializer is an lvalue and an rvalue reference otherwise. Each v_i_ is the name of an lvalue of type T_i_ that refers to the object bound to r_i_; the referenced type is T_i_.