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

2024-03-20


2285. Issues with structured bindings

Section: 9.6  [dcl.struct.bind]     Status: CD5     Submitter: Richard Smith     Date: 2016-07-01

[Accepted as a DR at the June, 2018 (Rapperswil) meeting.]

  1. What is the point of declaration of a name introduced by a structured binding? If it's the point at which it appears, we're missing a rule to make it ill-formed to reference the name before its type is deduced (similar to what we have for 'auto'). [Suggestion: point of declaration is after the identifier-list, program is ill-formed if the name is mentioned before the end of the initializer.]

  2. Are structured bindings permitted at namespace scope? There doesn't seem to be a rule against that. If so, what's their linkage? Is it intentional that static , extern are disallowed? Should we only allow automatic storage duration? [Suggestion: only permit automatic storage duration, per the design paper.]

  3. (If the answer to 2 is yes...) is the declaration in a variable template permitted to use structured bindings? If so, how do you name the result? (The bindings themselves aren't introduced as template-names by the current wording.) If not, we're missing a restriction on that. [Suggestion: no to question 2.]

  4. Did we intend to guarantee that the object whose members are denoted by bindings is kept "together":

  5.    auto f() -> int (&)[2];
       auto [x, y] = f();
       assert(&x + 1 == &y); // ok? 
    
       struct S { int a, b, c; }; // standard-layout 
       auto [a,b,c] = S();
       assert(&((S*)&a)->b == &b); // ok? 
    

    (If yes, this means we can't synthesize independent variables for each element of an array or struct that's bound in this way, and it's harder to remove dead components of a destructured object.) Obviously we may need to keep the object together if it has a non-trivial destructor. [Suggestion: do not allow reaching the complete object from a binding.]

  6. Should the copy->move promotion be permitted for a return of a structured binding?

  7.    struct A { string s; int n; };
       string f() {
         auto [s,n] = A();
         return s; // copy required here? 
       }
    

    [Suggestion: allow promotion to move -- as if the binding were a real local variable -- if the implicit underlying variable is not a reference. Maybe also allow NRVO, depending on answer to question 8.]

Notes from the April, 2017 teleconference:

Items 1 and 3 are core issues; item 4 is NAD - the bindings are kept together, which is implied by the existing rules about copying the object into a hidden temporary. The remaining items are questions for EWG and new items in "extension" status will be opened for them.

Proposed resolution, February, 2018:

  1. Change 6.4.2 [basic.scope.pdecl] paragraph 9 as follows and add the following new paragraph thereafter:

  2. The point of declaration for a function-local predefined variable (9.5 [dcl.fct.def] 9.5.1 [dcl.fct.def.general]) is immediately before the function-body of a function definition.

    The point of declaration of a structured binding (9.6 [dcl.struct.bind]) is immediately after the identifier-list of the structured binding declaration.

  3. Add the following as a new paragraph following 9.6 [dcl.struct.bind] paragraph 1:

  4. ...taken from the corresponding structured binding declaration. The type of the id-expression e is called E. [Note: E is never a reference type (Clause 7 [expr]). —end note]

    If the initializer refers to one of the names introduced by the structured binding declaration, the program is ill-formed.

(Note: In response to item 3, the current wording of Clause 13 [temp] paragraph 1 does not allow templated structured binding declarations, and no change is being proposed.)