A nice extension in C++ 11 is range-based for loops. They are both readable and safer as you do not need to manually specify the boundary conditions.
There are a few ways to walk such containers. One is via a constant iterator e.g.:
By now you will have seen the following range-based for loop e.g.:
for (auto const i : container) { }Another, if you wish to modify the data as you go is:
for (auto &i : container) { }However it may be 'simpler' to always do the following and use a forward reference:
for (auto &&i : container) { }This handles corner cases for things like vectors of bitfields that you cannot have a reference to. Here is such a corner case. The iterator provided is actually a thing called a proxy iterator, vector::reference. So, this will not compile:
#include <vector>
int main() {
std::vector<bool> v(8);
for (auto& e : v) { e = true; }
}But this will!
#include <vector>
int main() {
std::vector<bool> v(8);
for (auto&& e : v) { e = true; }
}Here is a full example:
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
// Create a vector of strings:
std::initializer_list< std::string > init1 = {"elem1", "elem1"};
std::vector< std::string > vec1(init1);
// Range based for loop iterator with a const:
for (const auto &i : vec1) {
std::cout << "vec1: walk " << i << std::endl;
}
// Range based for loop iterator with a modifiable reference:
for (auto &i : vec1) {
i += "+ stuff";
std::cout << "vec1: walk " << i << std::endl;
}
// Range based for loop iterator with forward reference:
for (auto &&i : vec1) {
i += "+ more stuff";
std::cout << "vec1: walk " << i << std::endl;
}
}To build:
cd range_based_for_loop rm -f *.o example clang -std=c++2a -Werror -g -O3 -fstack-protector-all -ggdb3 -Wall -c -o main.o main.cpp clang main.o -lstdc++ -o example ./example
Expected output:
# Create a vector of strings: # Range based for loop iterator with a const: vec1: walk elem1 vec1: walk elem1 # Range based for loop iterator with a modifiable reference: vec1: walk elem1+ stuff vec1: walk elem1+ stuff # Range based for loop iterator with forward reference: vec1: walk elem1+ stuff+ more stuff vec1: walk elem1+ stuff+ more stuff