Initial criticism:
1 / Typical textbook example
for(vector<int>::iterator it = a.begin(); it != a.end(); ++it)
There is no magic, but the question arises: is there a
ever changed in a loop that the boundary of the end can change?
2 / Improved
vector<int>::iterator end = a.end(); for(vector<int>::iterator it = a.begin(); it != end; ++it)
a.end()
is executed only once. However, since end
not const
, it can be changed inside the loop.
In addition, it enters the identifier end
in the outer region, polluting it.
Thus, there is a potential gain in performance, but not so much in clarity. In addition, it is much more detailed.
I would suggest several other ways:
3 / Best Guide
for(vector<int>::iterator it = a.begin(), end = a.end(); it != end; ++it)
It combines the advantages of v1
(fairly short-term, without external coverage) and v2
(performance), but it is not yet clear when end
ever modified inside the loop body.
4 / Boost-powered
BOOST_FOREACH(int& i, a)
Even shorter than v1
, immediately identified at a glance, the absence of external space leakage and the guarantee of complete iteration (it is impossible to change the boundaries).
Unfortunately:
- there are problems with commas in the type of the variable (because it depends on the preprocessor)
- compile-time errors are completely cryptic (since they depend on the preprocessor)
Note: theoretically, the std::foreach
algorithm could be made here, but to be honest ... too much effort in determining the predicate from the outside violates the locality of the code.
5 / C ++ 11 range operator for
for (int& i: a)
All advantages:
- Extremely difficult
- As best as C ++ hand-written loop
- Guaranteed full iteration, no questions.
And none of the problems (area leakage, preprocessor magic).
Personally, I use the C ++ 11 range when I can (projects for a hobby) and BOOST_FOREACH
differently (at work).
I avoid, like the plague, changing the container in which I repeat, preferring to rely on STL algorithms when I need to filter / delete elements ... It is too easy to spoil the boundary conditions and the iterator invalidity otherwise.