2

As a C++ newbie, I am just discovering iterators. I realize that one can use either an int or an iterators for loop through any container. Consider for example

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v;
    v.push_back(1);
    v.push_back(4);
    v.push_back(8);

    std::cout << "i is an int: "; 
    for (int i = 0; i<v.size();i++)
    {
       std::cout << v[i] << " ";
    }
    std::cout << std::endl;

    std::cout << "i is an iterator: ";
    for (std::vector<int>::iterator i = v.begin(); i!=v.end();i++)
    {
       std::cout << *i << " ";
    }
    std::cout << std::endl;
}

which outputs

i is an int: 1 4 8                                                                                                                                   
i is an iterator: 1 4 8  

Generally speaking,

  • is there any advantage of using one or the other method?
  • Is one faster than the other one?
  • When should I use an int and when should I use an iterator?
Remi.b
  • 17,389
  • 28
  • 87
  • 168
  • 1
    Note that since c++11, you have even for range: `for (int e : v) { std::cout << e << " "; }` – Jarod42 Oct 20 '16 at 17:17
  • 1
    And you can also do `auto i = v.begin()` so you don't really need to specify the (relatively complex) name of the type – ForceBru Oct 20 '16 at 17:18
  • The `int` version can't be generalized across all containers (`list`, `set`, etc.) while iterators (and range based for above) can be. – Chad Oct 20 '16 at 17:19
  • 1
    Can't the compiler take better advantage of loop unrolling in the indexing scenario? – AndyG Oct 20 '16 at 17:21

4 Answers4

2

The primary reason for iterators is to provide generality. In particular, a generic algorithm can traverse a variety of containers using an iterator whose type is passed as a template parameter:

template <class InIt>
void print(InIt b, InIt e) { 
    while (b != e) {
        std:cout << *b << ' ';
        ++b;
    }
}

In this case you get an advantage from the iterator because you can print a list or map (to give only a couple of example) just as well as a vector.

If you're working directly with a container of known type, that's not really an issue though. If you really just want to print out the items in a vector, using an integer to index into it works perfectly fine. Using an index instead of an iterator can have an advantage if you're modifying the collection instead of just reading its contents. For example, if you might do a push_back onto the vector inside the loop, an integer index would remain valid, but an iterator would potentially be invalidated1.

For the case you've shown, however, you probably want to consider a range-based for loop to avoid using either an index or an iterator:

for (auto i : v)
    std::cout << i << ' ';

1. Note that although this is true of standard iterators, it is possible to create an iterator type that remains valid in such a situation, if you really need/want it. For example: https://stackoverflow.com/a/7958561/179910

Community
  • 1
  • 1
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

Sometimes your algorithm will need the index, and in this case use the int, or size_t, to track the index. Otherwise use the iterator. Also note some containers can only be traversed with an iterator; list, map, etc.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
Tim Beaudet
  • 791
  • 7
  • 16
0

Iterators are more generic. You can use iterators to iterate over sequences that cannot be reasonably indexed (that's why there are several std::iterator categories). For example, standard input could be iterated over with istream_iterator and std::list doesn't support indexes.

On the other hand you have indexes, which are easy for the compilers to optimize, but far more rigid in terms of interface.

That being said, usage of iterators is ubiquitous in modern C++ and it's not a bad default, especially since you can use type deduction to avoid naming the annoyingly long types.

When using raw loops instead of algorithms, prefer ranged-for loops to the old-style loops:

for(auto const& elem : range){
    //...
}
krzaq
  • 16,240
  • 4
  • 46
  • 61
0

Similar question already exists Let me try to answer you questions one at a time: is there any advantage of using one or the other method? When should I use an int and when should I use an iterator? There are times you can not use an integer and you have to use an iterator!! However iterator is generally slower than integer.

What are the best and common practices?

It depends on your algorithm. If you are iterating over a fixed size array use integer, simple and easy. If you are using STL or developing your own data structure (link list as an instance) maybe the best choice is using an iterator.

Community
  • 1
  • 1
Aznaveh
  • 558
  • 8
  • 27