Say I have a vector of ints, and I want to print each of them using an iterator loop. The first way I've seen this done is like this:
1 2 3 4 5
std::vector<int> myVector = {1, 2, 3, 4, 5};
for (auto it = myVector.begin(); it != myVector.end(); ++it)
{
std::cout << *it << std::endl;
}
And the second way is this:
1 2 3 4 5
std::vector<int> myVector = {1, 2, 3, 4, 5};
for (auto it = myVector.begin(), end = myVector.end(); it != end; ++it)
{
std::cout << *it << std::endl;
}
Which way is better? Does the first one create an iterator to myVector.end() every time it loops, or does it somehow stay in memory? If it does stay in memory, does that make the first one better than the second?
Basically it should make almost no difference as long as your compiler isn't 20 years old. It will end up caching/optimizing it all away anyway. Always worth checking if you want a perfect answer for your environment though.
In any event, I think the choice between the two versions should be primarily based on grounds of readability. Without profiling data, micro-optimizations like this to me look premature.
Sums up my feelings on the matter.
In which case the C++11 version is my answer for this.
If there is a difference it will probably be very small and not worth thinking about. If you later find out this is a bottleneck you can always go back and change it later, but that is unlikely because the code inside the loop body is taking up most of the loop time anyway (unless you are doing something very simple).
If I had to choose between the two ways in the OP I would go for what is simpler/more readable which in my opinion is the first one.
#include <vector>
int foo( const std::vector<int>& vec )
{
int sum = 0 ;
for( auto it = vec.begin() ; it != vec.end(); ++it ) sum += *it ;
return sum ;
}
foo(std::vector<int, std::allocator<int> > const&):
mov rdx, QWORD PTR [rdi] ; move vec.begin() to 'it' (hold 'it' in register rdx)
mov rcx, QWORD PTR [rdi+8] ; move vec.end() to register rcx
xor eax, eax ; set 'sum' to zero (hold 'sum' in register eax)
cmp rdx, rcx ; compare it with vec.end()
je .L4 ; if equal, goto end (label L4)
.L3:
add eax, DWORD PTR [rdx] ; sum += *it
add rdx, 4 ; ++it
cmp rcx, rdx ; compare it with vec.end()
jne .L3 ; if not equal, goto beginning of loop (label L3)
rep ret
.L4:
rep ret
Performance being the same, essentially there are a few other things to consider.
Readability: how easy is it to understand the code
Correctness: can we minimise the chance of programming errors
Fragility: would we have to modify our code if something else changes?
(For instance, the type of the sequence is changed - from a vector to a list; to an array; to some user-defined sequence.)
On all counts this is the winner: for( const auto& v : seq ) { /* code does not resize the sequence */ }
This would be a close runner up : for( auto it = std::begin(seq) ; it != std::end(seq); ++it ) { ... }