Range-based for-loops are another syntactic convenience introduced in C++11. Range-based for-loops allow you to iterate through a sequence of values like arrays, containers, iterator ranges, and so on, without having to explicitly specify boundary conditions. It makes iterating less error-prone by obviating the need to specify boundary conditions.
The general syntax for range-based for-loop is:
for (range-declaration : sequence-expression) { statements; }
The sequence expression identifies a sequence of values like an array or a container, that is to be iterated through. The range declaration identifies a variable that would represent each element from the sequence in successive iterations of the loop. Range-based for-loops automatically recognize arrays, brace-enclosed sequences of expressions, and containers with begin
and end
member functions that return forward iterators. To iterate through all elements in an array, you write this:
T arr[N];
...
for (const auto& elem : arr) {
// do something on each elem
}
You can also iterate through a sequence of expressions enclosed in braces:
for (const auto& elem: {"Aragorn", "Gandalf", "Frodo Baggins"}) { // do something on each elem }
Iterating through elements in a container that exposes forward iterators through begin
and end
member functions is not all that different:
std::vector<T> vector;
...
for (const auto& elem: vector) {
// do something on each elem
}
The range expression declares a loop variable called elem
using auto
to deduce its type. This use of auto
in range-based for-loops is idiomatic and common. To traverse sequences encapsulated within other kinds of objects, range-based for-loops require that two namespace-level methods, begin
and end
, be available and be resolved via Argument Dependent Lookup (see Chapter 2, The First Brush with Boost's Utilities). Range-based for-loops are great for traversing sequences whose lengths remain fixed during traversal.
You can use the BOOST_FOREACH
macro to emulate the basic uses of C++11's range-based for-loops:
#include <boost/foreach.hpp> std::vector<std::string> names; ... BOOST_FOREACH(std::string& name, names) { // process each elem }
In the preceding example, we use the BOOST_FOREACH
macro to iterate through the elements of a vector of strings called names
, using a loop variable called name
of type string
. Using BOOST_FOREACH
, you can iterate over arrays, containers with member functions begin
and end
that return forward iterators, iterator pairs, and null-terminated character arrays. Note that C++11 range-based for-loops do not readily support the last two types of sequences. On the other hand, with BOOST_FOREACH
, you cannot deduce the type of the loop variable using the auto
keyword.