range for
The range-based for
statement
The range-based for
statement is a simpler and safer way to loop over the contents of a container or array.
It looks like this:
for (/* variable declaration */ : /* container or array */) { // statements }
Which, for a container, expands to:
for (auto p = container.begin(); p != container.end(); ++p) { /* variable declaration */ = *p; // statements }
For an array it expands to:
for (int n = 0; n != sizeof(array); ++n) { /* variable declaration */ = array[n]; // statements }
Normally you would use a variable declaration with auto, or possibly const auto&:
for (auto item : items) { // statements }
If you don't use auto, the values in the container or array must be convertible to whatever type you use.
For example:
#include <iostream> #include <string> #include <vector> int main() { std::vector<std::string> doctors = { "Strange", "Octopus", "Who" }; // You could use "std::string" instead of "auto" for (auto const& doc : doctors) { std::cout << "Paging Dr. " << doc << '\n'; } }
Output:
Paging Dr. Strange Paging Dr. Octopus Paging Dr. Who
If you use a non-const reference, you can change the values in the container or array within the loop:
For example:
Output:
1 2 3 4 2 4 6 8
The range-based for
statement is not only easier to write, it is safer.
You cannot accidently go past the end of a container or array, or make other mistakes like this:
std::vector<int> c1 = { 1, 2, 3 }; std::vector<int> c2 = { 4, 5, 6 }; // Mixing the begin/end from c1 and c2 by accident! // This causes undefined behaviour! for (auto p = c1.begin(); p != c2.end(); ++p) { std::cout << *p << '\n'; }
On the other hand, the range-based for
statement is more limited.
You can't start half-way through the sequence, and you can't advance by more than one item at a time.
You can keep track of where you are in the sequence, but it requires an extra variable.
(And of course, you can always end before the end of the sequence with a break statement.)