C++ is very flexible, and I want to understand for-loop operations more deeply. I'm hoping for a good comparison of each implementation and what is better/faster/more efficient. Additionally, it would be a perk to learn some other way of implementing a for-loop - and not necessarily something in the STL.
I'm looking for expert answers, not opinions. Notice the many limitations I've put on answers: answers pertain only to the specific for-loops mentioned, their limitations (which may not be intuitive), specific alternatives not in the STL, and specific enhancements.
How do these other for-loops (not the 'traditional') work differently/better?
What are the limitations of the other 'non-traditional' for-loops?
Example 1) Traditional for-loop is:
for(int i=0;i<SIZE;i++){
//do something for each iteration;
}
Example 2) Now lets say I have a vector of scores.
vector<int> scores = {77,91,100,88,85,68,95};
for (auto it = scores.begin(); it != scores.end(); ++it){
//do something for each iteration;
}
Example 3) Same scores vector, different loop.
for (auto& x: scores) //do something for each iteration;
I'm particularly interested in example 3, because it is so simple, I'm not sure what it's actually doing, yet functionally is the same as the other two.
You have access to i
that you can use to figure out whether you're in the first, last or some other iteration. Not usable with non-random-access containers, so not an option for generic code that must work with vectors and lists alike. Supported since the first version of c++ standard.
Works with all standard iterators and therefore appropriate for generic code. No access to iteration counter, but the count can be calculated with std::distance
, however, if the iterator is not random access, then that adds up the complexity of iteration. Figuring out if you are in first or last iteration is still constant time, though. Supported since the first version of c++ standard.
Much nicer syntax, but semantically equivalent to certain forms of 2. Sub-ranges can not be used: goes always from begin to end† (unless you break out). No way to access iteration counter. Did not exist prior to c++11. There also exists macro based implementations such as BOOST_FOREACH
that do a similar thing and support the older standard.
† Iterator ranges can be used with the range-based for loop to get around this. They're not part of the standard library, but there are third party implementations.
TL;DR
Version 3 is basically a short hand way of saying Version 2.
The item on the right scores
must support std::begin(scores)
and std::end(scores)
and becomes syntactically equivalent too:
for (auto& x: scores)
{
// STUFF
}
// Is the same as:
for(auto tmp = std::begin(scores); tmp != std::end(scores); ++tmp)
{
auto& x = *tmp;
// tmp not technically available.
// STUFF
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With