CWG Issue 900 (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


900. Lifetime of temporaries in range-based for

Section: 6.8.7 [class.temporary]Status: C++23Submitter: Thomas J. GritzanDate: 2009-05-12

[Accepted at the November, 2022 meeting as part of paper P2718R0.]

Temporaries created in the expression of the range-basedfor statement are not given special treatment, so they only persist to the end of the expression. This can lead to undefined behavior as __range and the iterators are used in the expansion of the statement. Such temporaries should have their lifetimes extended until the end of the statement.

Rationale (October, 2009):

In the expansion, expression is used to initialize a reference. If expression is a temporary, its lifetime is thus extended to that of the reference, which is the entire forstatement.

Additional notes, February, 2017:

Posting from Daniel Frey to the std-discussion group:

Some people have tried

namespace detail { template< class C > struct reverse_range { explicit reverse_range (C& _c) : c(_c) {} auto begin () { using std::rbegin; return rbegin(c); } auto end () { using std::rend; return rend(c); } private: C& c; }; }

template< class C > auto reverse (C& c) { return detail::reverse_range{c}; }

In an attempt to allow:

// some function std::vector foo();

// correct usage auto v = foo(); for( auto i : reverse(v) ) { std::cout << i << std::endl; }

// problematic usage for( auto i : reverse(foo()) ) { std::cout << i << std::endl; }

The problem is that the temporary returned by foo() is destructed before the loop starts executing. [This issue] was supposed to be about that, but considers only the top-level temporary.

It might be reasonable to make the range-based for treat the for-range-initializer like a function argument: all temporaries of the expression should be destructed after the execution of the loop. This also removes the only place where binding a reference to a temporary extends its lifetime implicitly, unseen by the user.

Notes from the February, 2017 meeting:

CWG was inclined to accept the suggested change but felt that EWG involvement was necessary prior to such a decision.