Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterators.. why use them? [duplicate]

Tags:

c++

iterator

stl

In the STL library some containers have iterators and it is commonly held that they are a superior way of iterating through these containers rather than simple for loops e.g.

for ( int i=0; i < vecVector.size(); i++ )
{

..

}

Can anyone tell me why and in what cases I should use iterators and in what cases the code snippet above please?

like image 928
Konrad Avatar asked Oct 07 '08 15:10

Konrad


People also ask

What is the benefit of using iterators?

Benefits of Iterators. Use of an iterator simplifies the code and makes it general. Benefits of using this iterator API include: treats variables of all types, sizes, and shapes uniformly, whether they fit in memory or not, even if a single row won't fit in memory.

Can iterators be reused?

iterators are not reusable; you need to get a fresh Iterator from the Iterable collection each time you want to iterate over the elements.

What is the distinct advantages of using iterators over simple for loop?

Iterator and for-each loop are faster than simple for loop for collections with no random access, while in collections which allows random access there is no performance change with for-each loop/for loop/iterator.

What are advantages of iterating a collection using iterator?

Advantages of Iterator in Java Iterator in Java supports both read as well as remove operations. If you are using for loop you cannot update(add/remove) the Collection whereas with the help of an iterator you can easily update Collection. It is a Universal Cursor for the Collection API.


3 Answers

Note that the usually implementation of vector won't use an "int" as the type of the index/size. So your code will at the very least provoke compiler warnings.

Genericity

Iterators increase the genericity of your code.

For example:

typedef std::vector<int> Container ;

void doSomething(Container & p_aC)
{
    for(Container::iterator it = p_aC.begin(), itEnd = p_aC.end(); it != itEnd; ++it)
    {
       int & i = *it ; // i is now a reference to the value iterated
       // do something with "i"
    }
}

Now, let's imagine you change the vector into a list (because in your case, the list is now better). You only need to change the typedef declaration, and recompile the code.

Should you have used index-based code instead, it would have needed to be re-written.

Access

The iterator should be viewed like a kind of super pointer. It "points" to the value (or, in case of maps, to the pair of key/value).

But it has methods to move to the next item in the container. Or the previous. Some containers offer even random access (the vector and the deque).

Algorithms

Most STL algorithms work on iterators or on ranges of iterators (again, because of genericity). You won't be able to use an index, here.

like image 57
paercebal Avatar answered Oct 02 '22 08:10

paercebal


Using iterators allows your code to be agnostic about the implementation of your container. If random access for your container is cheap, there isn't much difference performance-wise.

But in lots of cases you won't know whether that is the case. If you try do use your method on a linked list, for example, with subscripting, the container is going to have to walk the list on every iteration to find your element.

So unless you know for sure that random access to your container is cheap, use an iterator.

like image 17
Adam Bellaire Avatar answered Oct 02 '22 08:10

Adam Bellaire


If you use iterators as the arguments to your function you can decouple it from the type of "container" used. For example, you might direct the results of a function to console output rather than a vector (example below). This trick can be enormously powerful for reducing coupling between your classes. Loosely coupled classes are much easier to test.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template <typename InputIterator, typename OutputIterator>
void AddOne(InputIterator begin, InputIterator end, OutputIterator dest)
{
    while (begin != end)
    {
        *dest = *begin + 1;
        ++dest;
        ++begin;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> data;
    data.push_back(1);
    data.push_back(2);
    data.push_back(3);

    // Compute intermediate results vector and dump to console
    vector<int> results;
    AddOne(data.begin(), data.end(), back_inserter(results));
    copy(results.begin(), results.end(), ostream_iterator<int>(cout, " "));
    cout << endl;

    // Compute results and send directly to console, no intermediate vector required
    AddOne(data.begin(), data.end(), ostream_iterator<int>(cout, " "));
    cout << endl;

    return 0;
}
like image 3
Jamie Eisenhart Avatar answered Oct 02 '22 09:10

Jamie Eisenhart