CWG Issue 2312 (original) (raw)
This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-11-05
2312. Structured bindings and mutable
Section: 9.7 [dcl.struct.bind]Status: CD6Submitter: Richard SmithDate: 2016-08-11
[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.7 [dcl.struct.bind] paragraph 4, the type ofa 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.)
Proposed resolution, March, 2018: [SUPERSEDED]
Change 9.7 [dcl.struct.bind] paragraph 4 as follows:
...Designating the non-static data members of Eas m0, m1, m2, ... (in declaration order), each v_i_ is the name of an lvalue that refers to
the member m_i_of e and whose type is cv T_i_, where T_i_ is the declared type of that membere.m_i_; the referenced type iscv T_i_the type of e.m_i_. The lvalue is a bit-field if...
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.
Proposed resolution (April, 2020):
Change 9.7 [dcl.struct.bind] paragraph 5 as follows:
...Designating the non-static data members of Eas m0, m1,m2, ... (in declaration order), each v_i_ is the name of an lvalue that refers to the member m_i_of e and whose type is
cv T_i_, where T_i_ is the declared type of that memberthat of e.m_i_(7.6.1.5 [expr.ref]); the referenced type iscv T_i_the declared type of m_i_ if that type is a reference type, or the type of_e_.m_i_ 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 “
constint”, the type of the id-expression y is “const volatile double”. —_end example_]