This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
Consider:
struct S {}; const S f(); auto x = [&ref = f()] { return ref; }
Subclause 7.5.6.3 [expr.prim.lambda.capture] paragraph 6 specifies:
An init-capture inhabits the lambda scope (6.4.5 [basic.scope.lambda]) of the lambda-expression. An init-capture without ellipsis behaves as if it declares and explicitly captures a variable of the form “auto init-capture ;”, except that:
- if the capture is by copy (see below), the non-static data member declared for the capture and the variable are treated as two different ways of referring to the same object, which has the lifetime of the non-static data member, and no additional copy and destruction is performed, and
- if the capture is by reference, the variable's lifetime ends when the closure object's lifetime ends.
It is unclear whether the temporary returned by f() is lifetime-extended by being bound to a reference init-capture.
There is implementation divergence: gcc rejects the example; clang accepts and extends the lifetime of the temporary; MSVC and EDG accept and do not extend the lifetime.
Proposed resolution (reviewed by CWG 2024-03-01):
Change in 7.5.6.3 [expr.prim.lambda.capture] paragraph 6 as follows:
An init-capture inhabits the lambda scope (6.4.5 [basic.scope.lambda]) of the lambda-expression. An init-capture without ellipsis behaves as if it declares and explicitly captures a variable of the form “auto init-capture ;”, except that:
- if the capture is by copy (see below), the non-static data member declared for the capture and the variable are treated as two different ways of referring to the same object, which has the lifetime of the non-static data member, and no additional copy and destruction is performed, and
- if the capture is by reference and the reference would bind to an object that is the result of a temporary expression, the program is ill-formed, and
- if the capture is by reference, the variable's lifetime ends when the closure object's lifetime ends.