To iterate or to use a counter, that is the questi

2019-06-24 07:56发布

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
}

12条回答
甜甜的少女心
2楼-- · 2019-06-24 08:09

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:

template <class iter>
void my_algorithm(iter a, iter b) { 
    for (iter i=a; i!=b; ++i) 
        do_stuff(*i); 
}

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 (or Boost FOR_EACH) will probably work quite nicely.

查看更多
Animai°情兽
3楼-- · 2019-06-24 08:16

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.

查看更多
祖国的老花朵
4楼-- · 2019-06-24 08:17

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.

查看更多
小情绪 Triste *
5楼-- · 2019-06-24 08:18

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 other std functions like in <algorithms>.

查看更多
混吃等死
6楼-- · 2019-06-24 08:21

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:

typedef std::vector<int> MyIndexes; 
MyIndexes indexes;
for (Something::iterator iter = indexes.begin(); iter != indexes.end(); ++iter);

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.

查看更多
再贱就再见
7楼-- · 2019-06-24 08:23

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.

查看更多
登录 后发表回答