0

Which of the following method is better?

vector<int> vecInts;
// initialize vecInts;
// method ONE    
for( vector<int>::size_type szInd = 0; szInd < vecInts.size(); ++szInd )
{
  // process vecInts[szInd]
}

// method TWO
for( vector<int>::iterator iter = vecInts.begin(); iter != vecInts.end(); ++iter )
{
  // process *iter
}

During code review, I am always suggested by one person that I should replace the method one with iterator version and I argue that it doesn't matter. Am I right? Thank you

q0987
  • 34,938
  • 69
  • 242
  • 387
  • 1
    It's a question of style. I would be surprised if there were still compilers generating different code for the two loops. – Max Lybbert May 01 '14 at 18:21
  • 1
    There is a bigger problem than index vs iterator: the `size()` and `end()` are evaluated in each iteration. If the size of the vector is not changed, then they should be moved out of the loop – GuLearn May 01 '14 at 18:27
  • @YZ.learner The compiler actually yields code that calls those methods each time through the loop? –  May 01 '14 at 18:30
  • 1
    @Articuno That would depend on the implementation. But if the compiler is not sure if the size of the container would be changed during the loop, it has to evaluate it in each iteration – GuLearn May 01 '14 at 18:32
  • 1
    @Articuno The last time I measured (but that was some time ago), moving the call to `end()` out of the loop did make a difference. But only for very, very tight loops; it's not something you should worry about until the profiler tells you to. – James Kanze May 01 '14 at 18:35
  • See also: http://stackoverflow.com/questions/linked/131241?lq=1 – johnsyweb May 01 '14 at 19:01

3 Answers3

3

Use the more general, iterator version:

  • It can produce the same machine code on optimized builds (subject to quality of implementation).

  • It's a more general idiom, not specific to vectors. It removes emphasis of the vector nature of the container and concentrates on the loopy nature of the loop.

  • You can swap the container type later and won't need to touch your loop code (assuming you use a few more typedefs).

  • In debug builds you may gain access to debug iterators that allow for easier debugging.

Update: James makes a good point - I'm only referring to "when you want to iterate over a range". By contrast, if the numeric value of the indices, and thus the vector nature of the vector, is relevant, then you may like to use indices (e.g. for numeric algorithms; matrices, graphs, permutations, etc.). As a meta guideline, use the style that corresponds to the appropriate abstraction.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Point one is far from guaranteed. One may produced better code with one compiler, the other with another. – James Kanze May 01 '14 at 18:33
  • 1
    And as for point 4: the debug builds will also do bounds checking with an iterator. – James Kanze May 01 '14 at 18:33
  • @JamesKanze: If your compiler or library produce less-than-efficient iteration code in an optimized build, that should probably be a bug report... (I reworded it, though.) – Kerrek SB May 01 '14 at 18:34
  • Generally, given the typical implementation, I expect that if there is a difference, the iterator version is slightly faster. A lot depends on what happens in the loop, though; in many cases, the compiler will not be able to generate the same code (because indexing uses a pointer in the vector, but the iterator has its own pointer). – James Kanze May 01 '14 at 18:38
2

It depends on context. Using iterators is more idiomatic in the general C++, which means that they should be preferred, but if you need to iterate in parallel through several identically sized vector, then using the index allows you to use one variable instead of several. And there are communities where the index is more idiomatic: people versed in numerics seem to prefer it, for example. If you're working in such a community, then you should also use it. (But if you're receiving suggestions in code review to favor iterators, that's probably not the case.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
1

The difference is that in method two, the iterator gets invalidated if an element is inserted before the iterator. In method one, you will look at the same element twice.

On the other hand, when an element is inserted after the current position, with method two the iterator could get invalidated because of a reallocation, but method one will still work.

alain
  • 11,939
  • 2
  • 31
  • 51