Whenever someone starts using the STL and they have a vector, you usually see:
vector<int> vec ; //... code ... for( vector<int>::iterator iter = vec.begin() ; iter != vec.end() ; ++iter ) { // do stuff }
I just find that whole vector<int>::iterator
syntax sickitating. I know you can typedef vector<int>::iterator VecIterInt
, and that is slightly better..
But the question is, what's wrong with good ol':
for( int i = 0 ; i < vec.size() ; i++ ) { // code }
IMO, using either one is pretty much missing the point. Iterating over a collection should be done in an algorithm. Quite a bit of the time, an existing algorithm will do the job quite nicely, but when it doesn't, you're generally best off writing something yourself that's actually usable as a generic algorithm.
This is one of those rather strange cases where the generic code is often simpler (and easier to write) than the most specialized code. In particular, instead of the iterator being something like
std::map<std::string, my_type>::iterator
, the iterator type is a template parameter with whatever name you find convenient:But I'll repeat: quite a bit of the time, you can use an existing algorithm. For the case you cited, it appears that
std::for_each
(orBoost FOR_EACH
) will probably work quite nicely.The flagged answer is wrong. There's no 'access' going on is this code at all.
The real answer should be no difference in this case unless the vector implementation is exceedingly incompetent, except using an iterator will be slightly slower.
Iterator for something that is stored in an array is quite a silly concept. It's just done that way because some other cases can't be accesed directly as an array, so to be more general they encourage iterator use for everything. Even though iterators are ridiculously cumbersome, and only make sense to use in a few special cases.
As a general rule, not limiting ourselves to std::vector, iterators can be more efficient than indexing, since they have access to the internals of the collection and knows the state of the iteration.
In the case of std::vector, the iterator in the loop will reduce to pointer arithmetic when compiled with optimizations on. A clever compiler might be able to do the same with a counter loop, and there shouldn't be any difference in performance, but in general (for more complex collections) you should assume that an iterator will give you the fastest code.
Well when it comes to
std::vector
I think using the subscript operator in a loop is just fine, and probably about the same in terms of performance. The advantage to using an iterator comes when you want to use the vector with otherstd
functions like in <algorithms>.Always in two minds about this. To the computer it doesn't matter, the compiler is big enough to look after itself and will end up generating equally good code for either case.
But what about the programmer?
Seeing
for(int i=0;i<blah.size();i++)
my eye immediately reads this as "loop over all elements".While seeing:
I have to careful read each line to check that you aren't doing something tricky.
On the other hand seeing the for() loop makes me worry that the code is written by a C programmer who knows nothing about the STL and is going to be horribly designed.
I would recommend using the iterators simply because they are more generic. If later in your development cycle, you decide that a std::list<> would be better then a std::vector<> (perhaps you find out you have a performance problem because you need to pop elements from the head of the container), it will take less effort to change the iterator version.