For iterating or using a counter, this is a question

Whenever someone starts using 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 the whole syntax of the vector<int>::iterator syntax. I know that you can typedef vector<int>::iterator VecIterInt , and that is a little better.

But the question is what's wrong with good ol ':

  for (int i = 0; i <vec.size (); i ++)
 {
   // code
 }
+4
source share
12 answers

When you use an index to perform essentially sequential access to a container ( std::vector or something else), you impose a random access requirement on the underlying data structure, when in fact you do not need such access to your algorithm. The random access requirement is a pretty strong requirement compared to the much weaker sequential access requirement. Imposing a stronger requirement without good reason is a major design error.

So, the correct answer to your question is: use sequential (iterator) access when you can, use random (index) access only when you absolutely need it. Whenever possible, try to avoid access to the index.

If your algorithm relies critically on random access to the container, it becomes an external requirement of the algorithm. In this case, you can use access to the index without any reservations. However, if it is possible to implement the same algorithm using only iterators, it is recommended to stick to iterators only, i.e. Rely exclusively on sequential access.

Of course, the above rule, although true, makes sense only in the code, to a certain extent is general. If some other part of the code is so specific that you know for sure that the data structure you are working with is std::vector and will always be std::vector , then the access method no longer matters. Use whatever you prefer. However, I would still avoid accessing the index in situations where sequential access is sufficient.

+11
source

Well, when it comes to std::vector , I think that using the index operator in a loop is just fine and probably about the same in terms of performance. The advantage of using an iterator is when you want to use a vector with other std functions, as in <algorithms>.

+7
source

I do not think my argument is very strong, but I almost always use the iterator version.

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

Now, if I need to change a vector to a list or something like that, I only need to change my typedef. This has been helpful several times. auto keyword will do it better, but I can't wait for C ++ 0x loop :)

+2
source

I usually use a for loop for vectors - for me, this is the canonical way to deal with such things. And don't let anyone tell you that iterators are faster - see What happens faster, iterating an STL vector using the :: iterator vector or using ()? .

Also, one thing that extreme proponents of iterators and constructs such as foreach tend to ignore is that with a for loop you really have an integer index, you can do something other than accessing the elements of the collection That can be very useful in all situations.

However, if I were to use the STL algorithm or iterate over another type of container, for example std :: map, I would certainly use iterators.

+1
source

As a rule, not limited to std :: vector, iterators can be more efficient than indexing, since they have access to the internal elements of the collection and know the state of the iteration.

In the case of std :: vector, the iterator in the loop will be reduced to pointer arithmetic when compiling with optimization. A smart compiler can do the same with the loop loop, and there shouldn't be any difference in performance, but overall (for more complex collections) you should assume that the iterator will provide you with the fastest code.

+1
source

With C ++ 0x, you will not have this dilemma. You will use the new for , which is actually used by foreach :)

+1
source

I would recommend using iterators simply because they are more general. If later in your development cycle you decide that std :: list <> will be better than std :: vector <> (you may find that you have a performance problem because you need to stroke the elements from the container header), changing the iterator version will take less effort.

+1
source

If you create, use and destroy a vector all within the same area, there is not much benefit for using iterator abstraction, but for richer containers, for example, std::map , the overhead is worth it.

Iterators are great for general programming. None of the mechanisms and accounting do not hide the intent of the code, and you get more flexibility. Want to copy one vector to another?

 std::vector<int> v1, v2; // ... std::copy(v1.begin(), v1.end(), v2.begin()); 

What about std::cout instead?

 std::ostream_iterator<int> output(std::cout, " "); std::copy(v1.begin(), v2.end(), output); 

Iterators allow one template to handle all kinds of cases.

+1
source

Persons, I prefer to use an iterator for iteration. Shows intent better than index access, IMHO, and the coding idiom is the same for different containers.

0
source

Always in two minds about it. It doesnโ€™t matter for a computer, the compiler is large enough to take care of itself and as a result will generate equally good code for any occasion.

But what about the programmer?

Seeing for(int i=0;i<blah.size();i++) , my eye immediately reads this as a "loop over all elements."
Seeing:

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

I have to read each line carefully to verify that you are not doing something complicated.

On the other hand, looking at the for () loop makes me worry that the code is written by a C programmer who knows nothing about the STL and will be terribly designed.

0
source

The marked answer is incorrect. There is no access to this code at all.

The real answer should not be a difference in this case, if the vector implementation is extremely incompetent, except for using an iterator it will be a bit slower.

An iterator for something that is stored in an array is pretty stupid. This is simply because some other cases cannot be directly related to the array, therefore, to be more general, they encourage the iterator to use everything. Although iterators are ridiculously bulky and make sense only in a few special cases.

0
source

IMO, using one of them, is pretty much missing the point. Iteration over the collection should be performed in an algorithm. Just a little while, the existing algorithm will do the job pretty well, but when itโ€™s not, itโ€™s usually better for you to write something by itself, which can be used as a general algorithm.

This is one of those rather strange cases where common 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 type of the iterator is a template parameter with any name convenient for you:

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

But I repeat: quite a bit of time, you can use the existing algorithm. For the case you pointed out, it seems that std::for_each (or Boost FOR_EACH ) will probably work pretty well.

0
source

All Articles