8 Statements [stmt.stmt]

8.6 Iteration statements [stmt.iter]

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

The range-based for statement is equivalent to
{
   init-statement
   auto &&range = for-range-initializer ;
   auto begin = begin-expr ;
   auto end = end-expr ;
   for ( ; begin != end; ++begin ) {
      for-range-declaration = * begin ;
      statement
   }
}
where
  • if the for-range-initializer is an expression, it is regarded as if it were surrounded by parentheses (so that a comma operator cannot be reinterpreted as delimiting two init-declarators);
  • range, begin, and end are variables defined for exposition only; and
  • begin-expr and end-expr are determined as follows:
    • 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.
      If R is an array of unknown bound or an array of incomplete type, the program is ill-formed;
    • if the type of range is a reference to a class type C, and searches in the scope of C ([class.member.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;
    • otherwise, begin-expr and end-expr are begin(range) and end(range), respectively, where begin and end undergo argument-dependent lookup ([basic.lookup.argdep]).
      [Note 1: 
      Ordinary unqualified lookup ([basic.lookup.unqual]) is not performed.
      — end note]
[Example 1: int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) x *= 2; — end example]
[Note 2: 
The lifetime of some temporaries in the for-range-initializer is extended to cover the entire loop ([class.temporary]).
— end note]
[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() extended for (auto e : f2(g())) {} // undefined behavior } — end example]
In the decl-specifier-seq of a for-range-declaration, each decl-specifier shall be either a type-specifier or constexpr.
The decl-specifier-seq shall not define a class or enumeration.