Title
Structured bindings and mutable
Status
cd6
Section
9.6 [dcl.struct.bind]
Submitter
Richard Smith

Created on 2016-08-11.00:00:00 last changed 20 months ago

Messages

Date: 2020-04-15.00:00:00

Proposed resolution (April, 2020):

Change 9.6 [dcl.struct.bind] paragraph 5 as follows:

...Designating the non-static data members of E as m0, m1, m2, ... (in declaration order), each vi is the name of an lvalue that refers to the member mi of e and whose type is cv Ti, where Ti is the declared type of that member that of e.mi (7.6.1.5 [expr.ref]); the referenced type is cv Ti the declared type of mi if that type is a reference type, or the type of e.mi otherwise. The lvalue is a bit-field if that member is a bit-field.

[Example 2:

  struct S { mutable int x1 : 2; volatile double y1; };
  S f();
  const auto [ x, y ] = f();

The type of the id-expression x is “const int”, the type of the id-expression y is “const volatile double”. —end example]

Date: 2018-06-15.00:00:00

Notes from the June, 2018 meeting:

It was observed that this resolution does not handle members with reference type correctly. The main problem seems to be the statement in 7.6.1.5 [expr.ref] paragraph 4, which directly handles members with reference type rather than allowing the type of the member to be the result type and relying on the general rule that turns reference-typed expressions into lvalues.

Date: 2020-12-15.00:00:00

Proposed resolution, March, 2018: [SUPERSEDED]

Change 9.6 [dcl.struct.bind] paragraph 4 as follows:

...Designating the non-static data members of E as m0, m1, m2, ... (in declaration order), each vi is the name of an lvalue that refers to the member mi of e and whose type is cv Ti, where Ti is the declared type of that member e.mi; the referenced type is cv Ti the type of e.mi. The lvalue is a bit-field if...
Date: 2020-11-15.00:00:00

[Accepted at the November, 2020 meeting.]

An example like the following is currently ill-formed:

  struct A { mutable int n; };
  void f() {
    const auto [a] = A();
    a = 0;
  }

According to 9.6 [dcl.struct.bind] paragraph 4, the type of a is const int, since the implicitly-declared variable is const. This seems obviously wrong: the member n is mutable, so the member access expression e.n has type int, which should also be the type of a. (mutable should presumably be taken into account when forming the referenced type too, so that decltype(a) is int as would presumably be expected, rather than const int.)

History
Date User Action Args
2022-08-19 07:54:33adminsetstatus: drwp -> cd6
2021-02-24 00:00:00adminsetstatus: dr -> drwp
2020-12-15 00:00:00adminsetmessages: + msg6326
2020-12-15 00:00:00adminsetmessages: + msg6325
2020-12-15 00:00:00adminsetstatus: ready -> dr
2018-04-11 00:00:00adminsetmessages: + msg6175
2018-04-11 00:00:00adminsetstatus: drafting -> ready
2016-08-11 00:00:00admincreate