[stmt.ranged]

# 8 Statements [[stmt]](./#stmt)

## 8.6 Iteration statements [[stmt.iter]](stmt.iter#stmt.ranged)

### 8.6.5 The range-based for statement [stmt.ranged]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L703)

The range-based for statement

for ( [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") : [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")

is equivalent to

{  
 [*init-statement*](stmt.pre#nt:init-statement "8.1 Preamble [stmt.pre]")opt  
 auto &&*range* = [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") ;  
 auto *begin* = *begin-expr* ;  
 auto *end* = *end-expr* ;  
 for ( ; *begin* != *end*; ++*begin* ) {  
 [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") = * *begin* ;  
 [*statement*](stmt.pre#nt:statement "8.1 Preamble [stmt.pre]")  
 }  
}

where

- [(1.1)](#1.1)

if the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") is an [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]"),
it is regarded as if it were surrounded by parentheses (so that a comma operator
cannot be reinterpreted as delimiting two [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1 General [dcl.decl.general]")*s*);

- [(1.2)](#1.2)

*range*, *begin*, and *end* are variables defined for
exposition only; and

- [(1.3)](#1.3)

*begin-expr* and *end-expr* are determined as follows:
  * [(1.3.1)](#1.3.1)

      if the type of *range* is a reference to an
array type R, *begin-expr* and *end-expr* are*range* and *range* + N, respectively,
where N is
the array bound[.](#1.3.1.sentence-1)
      If R is an array of unknown bound or an array of
incomplete type, the program is ill-formed;

  * [(1.3.2)](#1.3.2)

      if the type of *range* is a reference to a
class type C, and
searches in the scope of C ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))
for the names begin and end each find at least one declaration,*begin-expr* and *end-expr* are*range*.begin() and *range*.end(),
respectively;

  * [(1.3.3)](#1.3.3)

      otherwise, *begin-expr* and *end-expr* arebegin(*range*) and end(*range*), respectively,
where begin and end undergo
argument-dependent lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))[.](#1.3.3.sentence-1)
      [*Note [1](#note-1)*:
      Ordinary unqualified lookup ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup")) is not
performed[.](#1.3.3.sentence-2)
 â *end note*]

[*Example [1](#example-1)*: int array[5] = { 1, 2, 3, 4, 5 };for (int& x : array) x *= 2; â *end example*]

[*Note [2](#note-2)*:

The lifetime of some temporaries in the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1 Preamble [stmt.pre]") is extended to cover the entire loop ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#1.sentence-2)

â *end note*]

[*Example [2](#example-2)*: using T = std::list<int>;const T& f1(const T& t) { return t; }const T& f2(T t) { return t; } T g();

void foo() {for (auto e : f1(g())) {} // OK, lifetime of return value of g() extendedfor (auto e : f2(g())) {} // undefined behavior} â *end example*]
