Lifetime of temporaries in range-based for
6.7.7 [class.temporary]
Thomas J. Gritzan

Created on 2009-05-12.00:00:00 last changed 4 months ago


Date: 2017-02-15.00:00:00

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.

Date: 2022-11-20.07:54:16

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); }
      C& c;

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

In an attempt to allow:

  // some function
  std::vector<int> 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.

Date: 2009-10-15.00:00:00

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 for statement.

Date: 2022-11-15.00:00:00

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

Temporaries created in the expression of the range-based for 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.

Date User Action Args
2023-07-16 13:00:43adminsetstatus: open -> c++23
2023-07-16 13:00:43adminsetstatus: drwp -> open
2023-02-18 18:43:04adminsetstatus: dr -> drwp
2022-11-25 05:14:04adminsetstatus: drwp -> dr
2022-11-20 07:54:16adminsetstatus: extension -> drwp
2018-02-27 00:00:00adminsetmessages: + msg6033
2018-02-27 00:00:00adminsetmessages: + msg6032
2018-02-27 00:00:00adminsetstatus: nad -> extension
2009-11-08 00:00:00adminsetmessages: + msg2486
2009-11-08 00:00:00adminsetstatus: open -> nad
2009-05-12 00:00:00admincreate