Range-based for loop (since C++11)

From cppreference.com
< cpp‎ | language

Executes a for loop over a range.

Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.

Contents

[edit] Syntax

attr(optional) for ( range_declaration : range_expression ) loop_statement
attr(C++11) - any number of attributes
range_declaration - a declaration of a named variable, whose type is the type of the element of the sequence represented by range_expression, or a reference to that type. Often uses the auto specifier for automatic type deduction
range_expression - any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.
statement - any statement, typically a compound statement, which is the body of the loop

[edit] Explanation

The above syntax produces code similar to the following (__range, __begin and __end are for exposition only):

{
auto && __range = range_expression ;
for (auto __begin = begin_expr,
__end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}

}

range_expression is evaluated to determine the sequence or range to iterate. Each element of the sequence, in turn, is dereferenced and assigned to the variable with the type and name given in range_declaration.

begin_expr and end_expr are defined as follows:

  • If __range is an array, then begin_expr is __range and end_expr is (__range + __bound), where __bound is the number of elements in the array (if the array has unknown size or is of an incomplete type, the program is ill-formed)
  • If __range's type is a class type with either or both a begin or an end member function, then begin_expr is __range.begin() and end_expr is __range.end();
  • Otherwise, begin_expr is begin(__range) and end_expr is end(__range), which are found via argument-dependent lookup (non-ADL lookup is not performed).

If range_expression returns a temporary, its lifetime is extended until the end of the loop, as indicated by binding to the rvalue reference __range, but beware that the lifetime of any temporary within range_expression is not extended.

Just as with a traditional loop, a break statement can be used to exit the loop early and a continue statement can be used to restart the loop with the next element.

attr represents an optional number of attributes.

[edit] Notes

If the initializer (range_expression) is a braced-init-list, __range is deduced to be std::initializer_list<>&&

It is safe, and in fact, preferable in generic code, to use deduction to rvalue reference, for(auto&& var : sequence). In C++17, this form is likely to be simplified to for(var : sequence).

[edit] Keywords

for

[edit] Example

#include <iostream>
#include <vector>
 
int main() 
{
    std::vector<int> v = {0, 1, 2, 3, 4, 5};
 
    for (const int &i : v) // access by const reference
        std::cout << i << ' ';
    std::cout << '\n';
 
    for (auto i : v) // access by value, the type of i is int
        std::cout << i << ' ';
    std::cout << '\n';
 
    for (auto&& i : v) // access by reference, the type of i is int&&
        std::cout << i << ' ';
    std::cout << '\n';
 
    for(int n : {0,1,2,3,4,5}) // the initializer may be a braced-init-list
        std::cout << n << ' ';
    std::cout << '\n';
}

Output:

0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5

[edit] See also

applies a function to a range of elements
(function template)