This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118f. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-11-07
[Accepted as a DR at the June, 2024 meeting.]
Consider:
auto [a, b] = f(X{});IfX is a tuple-like type, this is transformed toapproximately the following:
auto e = f(X{}); T1 &a = get<0>(std::move(e)); T2 &b = get<1>(std::move(e));However, the sequencing of the initializations of e, a, and b isnot specified. Further, the temporaryX{} should bedestroyed after the initializations of a and b.
Possible resolution [SUPERSEDED]:
Change in 6.10.1 [intro.execution] paragraph 5 as follows:
Afull-expression is...
- an unevaluated operand (7.2.3 [expr.context]),
- aconstant-expression (7.7 [expr.const]),
- an immediate invocation (7.7 [expr.const]),
- aninit-declarator (9.3 [dcl.decl]) oramem-initializer (11.9.3 [class.base.init]), including theconstituent expressions of the initializer,
- theinitializers for all uniquely-namedvariables introduced by a structured binding declaration(9.7 [dcl.struct.bind]), including the constituent expressions ofall initializers,
- an invocation of a destructor generated atthe end of the lifetime of an object other than a temporary object(6.8.7 [class.temporary]) whose lifetime has not been extended, or
- an expression that is not a subexpression of another expressionand that is not otherwise part of a full-expression.
Change in 9.7 [dcl.struct.bind] paragraph 4 as follows:
... Each vi is the name of an lvalue of type Tithat refers to the object bound to ri; the referenced typeis Ti.The initialization of e is sequenced before the initialization ofany ri. The initialization of ri is sequencedbefore the initialization of rj if i < j.
CWG 2024-05-03
CWG tentatively agreed that all temporaries in a structured binding(including those from default arguments ofget invocations)should persist until the semicolon on the declaration as written.
Possible resolution [SUPERSEDED]:
Change in 6.10.1 [intro.execution] paragraph 5 as follows:
Afull-expression is...
- an unevaluated operand (7.2.3 [expr.context]),
- aconstant-expression (7.7 [expr.const]),
- an immediate invocation (7.7 [expr.const]),
- aninit-declarator (9.3 [dcl.decl]), aninitializer of a structuredbinding declaration (9.1 [dcl.pre]), oramem-initializer (11.9.3 [class.base.init]), including theconstituent expressions of the initializer,
- an invocation of a destructor generated atthe end of the lifetime of an object other than a temporary object(6.8.7 [class.temporary]) whose lifetime has not been extended, or
- an expression that is not a subexpression of another expressionand that is not otherwise part of a full-expression.
Change in 9.7 [dcl.struct.bind] paragraph 4 as follows:
... Each vi is the name of an lvalue of type Tithat refers to the object bound to ri; the referenced typeis Ti.The initialization of e is sequenced before the initialization ofany ri. The initialization of each ri is sequencedbefore the initialization of any rj where i < j.
Append a new paragraph at the end of 9.7 [dcl.struct.bind] as follows:
... [ Example: ...The type of the id-expression x is "int", the type of the id-expression y is "const volatile double". -- end example ]
The initialization ofe and of any ri are sequencedbefore the destruction of any temporary object introduced bytheinitializer fore or by theinitializers forthe ri. The temporary objects are destroyed in thereverse order of their construction.
CWG 2024-06-14
The specification for the lifetime of temporaries should be movedto 6.8.7 [class.temporary].)
Proposed resolution (approved by CWG 2024-06-28):
Change in 6.8.7 [class.temporary] paragraph 5 as follows:
There arefourfive contexts in whichtemporaries are destroyed at a different point than the end of thefull-expression. ...
Insert a new paragraph after 6.8.7 [class.temporary] paragraph 7 as follows:
The fourth context is when a temporary object is created inthefor-range-initializer of a range-based for statement. Ifsuch a temporary object would otherwise be destroyed at the end ofthefor-range-initializer full-expression, the object persistsfor the lifetime of the reference initialized bythefor-range-initializer.
The fifth context is when a temporary object is created in astructured binding declaration (9.7 [dcl.struct.bind]). Anytemporary objects introduced by theinitializers for thevariables with unique names are destroyed at the end ofthe structured binding declaration.
Change in 6.10.1 [intro.execution] paragraph 5 as follows:
Afull-expression is...
- an unevaluated operand (7.2.3 [expr.context]),
- aconstant-expression (7.7 [expr.const]),
- an immediate invocation (7.7 [expr.const]),
- aninit-declarator (9.3 [dcl.decl])(including such introduced by a structured binding (9.7 [dcl.struct.bind])) oramem-initializer (11.9.3 [class.base.init]), including theconstituent expressions of the initializer,
- an invocation of a destructor generated atthe end of the lifetime of an object other than a temporary object(6.8.7 [class.temporary]) whose lifetime has not been extended, or
- an expression that is not a subexpression of another expressionand that is not otherwise part of a full-expression.
Change in 9.7 [dcl.struct.bind] paragraph 4 as follows:
... Each vi is the name of an lvalue of type Tithat refers to the object bound to ri; the referenced typeis Ti.The initialization of e is sequenced before the initialization ofany ri. The initialization of each ri is sequencedbefore the initialization of any rj where i < j.