tags:

views:

245

answers:

9

Hello all, I just wanted to know what is the main advantage of using the iterators over the array indices. I have googled but i am not getting the right answer.

+6  A: 

All of the standard containers provide the iterator concept. An iterator knows how to find the next element in the container, especially when the underlying structure isn't array-like. Array-style operator[] isn't provided by every container, so getting in the habit of using iterators will make more consistent-looking code, regardless of the container you choose.

Kristo
+3  A: 

You can abstract the collection implementation away.

codymanix
+9  A: 

I presume you are talking about when using a vector, right?

The main advantage is that iterator code works for all stl containers, while the array indexing operator [] is only available for vectors and deques. This means you are free to change the underlying container if you need to without having to recode every loop. It also means you can put your iteration code in a template and it will work for any container, not just for deques and vectors (and arrays of course).

T.E.D.
Also, you can write a custom iterator that could load data from a database, or generate data using some algorithm. It is extremely flexible. The tradeoff is, that iterators can hide arbitralily complex operations (e.g. access a database over the network), and that can lead to confusion about the slow execution of the code as well as problems with exception-safety.
Space_C0wb0y
`std::deque` also has an `operator[]`
mxp
Operator[] can hide arbitrarily complex operations as well.
Ryan
@mxp: Thanks. I thought there was another, but I failed to find it when I tried looking it up. The answer is fixed.
T.E.D.
So only if we are using data structures other than arrays it best to use the iterators right?
PrithviRaj
`[]` is available to maps/unordered_maps too. ;)
KennyTM
@KennyTM: Well, yeah. I'm not really counting that though, as the index type for those isn't nessecarily iterable itself (for instance strings). Sometimes extra precision in an answer only confuses things.
T.E.D.
Yes, but in the case of maps/unordered_maps we can use it only by overloading the [] operator right whose implementation will be almost similar to iterators for finding the node.
PrithviRaj
@prithviraj: Well, arrays don't really come with iterators, so you can't. Some would say that's one reason why you should always use vectors instead. However, there are some situations where you *want* the direct access `[]` (or `at`) provides.
T.E.D.
@prithviraj: The point of iterators is more important when you are designing a library. You do not have to worry how the user of your library represents his data, as long as he provides iterators. Using `operator[]` makes this much harder for users. You should read up on STL-Concepts to understand the differences.
Space_C0wb0y
+2  A: 

There are many data structures, e.g. hash tables and linked lists cannot be naturally or quickly indexed, but they are indeed traversable. Iterators act as an interface that let you walk on any data structure without knowing the actual implementation of the source.

KennyTM
A: 

As well as the points in other answers, iterators can also be faster (specifically compared to operator[]), since they are essentially iteration by pointer. If you do something like:

for (int i = 0; i < 10; ++i)
{
    my_vector[i].DoSomething();
}

Every iteration of the loop unnecessarily calculates my_vector.begin() + i. If you use iterators, incrementing the iterator means it's already pointing to the next element, so you don't need that extra calculation. It's a small thing, but can make a difference in tight loops.

AshleysBrain
No, a simple `+` seldom takes lots of cycles.
KennyTM
All tests I have done indicate there is no real difference in speed between iterators and op[] for vectors. If anything, op[] is slightly faster.
anon
@Neil: I have also tested this and concluded that iterators are *slightly* faster. You are right though that "there is no real difference." And I'm sure it depends on the implementation. You probably tested on one where iterators were not optimally implemented...
Oh, fair enough then.
AshleysBrain
@STingRaySC I suppose it is inconceivable that you were using an implementation where operator[] was not optimally implemented?
anon
@Neil: I'm really starting to warm up to your sense of overly-defensive-egotistical-pseudo-humor. All kidding aside, I suppose it's possible (hence my use of the word *probably*).
How about something other than a vector? An iterator could easily be more efficient than operator[] for a deque.
Mark Ransom
A: 

To expand upon previous answers:

  1. Writing a loop with operator[] constrains you to a container that supports [] and uses the same index/size type. Otherwise you'd need to rewrite every loop to change the container.

  2. Even if your container supports [], it may not be optimal for sequential traversing. [] is basically a random-access operator, which is O(1) for vector but could be as bad as O(n) depending on the underlying container.

  3. This is a minor point, but if you use iterators, your loop could be more easily moved to using the standard algorithms, e.g. std::for_each.

Ryan
+1  A: 

The STL contains algorithms, such as transform and for_each that operate on containers. They don't accept indices, but use iterators.

Iterators help hide the container implementation and allow the programmer to focus more on the algorithm. The for_each function can be applied to anything that supports a forward iterator.

Thomas Matthews
A: 

One other slight difference is that you can't use erase() on an element in a vector by index, you must have an iterator. No big deal since you can always do "vect.begin() + index" as your iterator, but there are other considerations. For example, if you do this then you must always check your index against size() and not some variable you assigned that value.

None of that is really too much worth worrying about but if given the choice I prefer iterator access for the reasons already stated and this one.

Noah Roberts
A: 

I would say it's more a matter of consistency and code reuse.

  • Consistency in that you will use all other containers with iterators
  • Code reuse in that algorithms written for iterators cannot be used with the subscript operator and vice versa... and the STL has lots of algorithms so you definitely want to build on it.

Finally, I'd like to say that even C arrays have iterators.

const Foo* someArray = //...
const Foo* otherArray = new Foo[someArrayLength];

std::copy(someArray, someArray + someArrayLength, otherArray);

The iterator_traits class has been specialized so that pointers or a model of RandomAccessIterator.

Matthieu M.