Why use iterators instead of array indices?

0 votes
asked Sep 25, 2008 by jason-baker

Take the following two lines of code:

for (int i = 0; i < some_vector.size(); i++)
{
    //do stuff
}

And this:

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end();
    some_iterator++)
{
    //do stuff
}

I'm told that the second way is preferred. Why exactly is this?

25 Answers

0 votes
answered Jan 16, 2008 by jason-baker

After having learned a little more on the subject of this answer, I realize it was a bit of an oversimplification. The difference between this loop:

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end();
    some_iterator++)
{
    //do stuff
}

And this loop:

for (int i = 0; i < some_vector.size(); i++)
{
    //do stuff
}

Is fairly minimal. In fact, the syntax of doing loops this way seems to be growing on me:

while (it != end){
    //do stuff
    ++it;
}

Iterators do unlock some fairly powerful declarative features, and when combined with the STL algorithms library you can do some pretty cool things that are outside the scope of array index administrivia.

0 votes
answered Jan 25, 2008 by adam-pierce

I don't think it makes much difference for a vector. I prefer to use an index myself as I consider it to be more readable and you can do random access like jumping forward 6 items or jumping backwards if needs be.

I also like to make a reference to the item inside the loop like this so there are not a lot of square brackets around the place:

for(size_t i = 0; i < myvector.size(); i++)
{
    MyClass &item = myvector[i];

    // Do stuff to "item".
}

Using an iterator can be good if you think you might need to replace the vector with a list at some point in the future and it also looks more stylish to the STL freaks but I can't think of any other reason.

0 votes
answered Jan 25, 2008 by pat-notz

Aside from all of the other excellent answers... int may not be large enough for your vector. Instead, if you want to use indexing, use the size_type for your container:

for (std::vector<Foo>::size_type i = 0; i < myvector.size(); ++i)
{
    Foo& this_foo = myvector[i];
    // Do stuff with this_foo
}
0 votes
answered Jan 25, 2008 by colen

The second form represents what you're doing more accurately. In your example, you don't care about the value of i, really - all you want is the next element in the iterator.

0 votes
answered Jan 25, 2008 by pat-notz

Another nice thing about iterators is that they better allow you to express (and enforce) your const-preference. This example ensures that you will not be altering the vector in the midst of your loop:


for(std::vector<Foo>::const_iterator pos=foos.begin(); pos != foos.end(); ++pos)
{
    // Foo & foo = *pos; // this won't compile
    const Foo & foo = *pos; // this will compile
}
0 votes
answered Jan 25, 2008 by sergey-stolyarov

During iteration you don't need to know number of item to be processed. You just need the item and iterators do such things very good.

0 votes
answered Jan 25, 2008 by leonardo-constantino

Even better than "telling the CPU what to do" (imperative) is "telling the libraries what you want" (functional).

So instead of using loops you should learn the algorithms present in stl.

0 votes
answered Jan 25, 2008 by krirk

I always use array index because many application of mine require something like "display thumbnail image". So I wrote something like this:

some_vector[0].left=0;
some_vector[0].top =0;<br>

for (int i = 1; i < some_vector.size(); i++)
{

    some_vector[i].left = some_vector[i-1].width +  some_vector[i-1].left;
    if(i % 6 ==0)
    {
        some_vector[i].top = some_vector[i].top.height + some_vector[i].top;
        some_vector[i].left = 0;
    }

}
0 votes
answered Jan 25, 2008 by user22044

Several good points already. I have a few additional comments:

  1. Assuming we are talking about the C++ standard library, "vector" implies a random access container that has the guarantees of C-array (random access, contiguos memory layout etc). If you had said 'some_container', many of the above answers would have been more accurate (container independence etc).

  2. To eliminate any dependencies on compiler optimization, you could move some_vector.size() out of the loop in the indexed code, like so:

    const size_t numElems = some_vector.size();
    for (size_t i = 0; i 
  3. Always pre-increment iterators and treat post-increments as exceptional cases.

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end(); ++some_iterator){ //do stuff }

So assuming and indexable std::vector<> like container, there is no good reason to prefer one over other, sequentially going through the container. If you have to refer to older or newer elemnent indexes frequently, then the indexed version is more appropropriate.

In general, using the iterators is preferred because algorithms make use of them and behavior can be controlled (and implicitly documented) by changing the type of the iterator. Array locations can be used in place of iterators, but the syntactical difference will stick out.

0 votes
answered Jan 25, 2008 by all2one

For container independence

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...