=====C++ Iterators=====
Iterators are used to access elements of a sequence, and can be used
in a similar manner to pointers. For example, one might use an iterator to step
through the elements of a vector.
The following code creates and uses an iterator with a vector:
vector the_vector;
vector::iterator the_iterator;
for( int i=0; i < 10; i++ ) the_vector.push_back(i);
int total = 0;
the_iterator = the_vector.begin();
while( the_iterator != the_vector.end() ) {
total += *the_iterator;
++the_iterator;
}
cout << "Total=" << total << endl;
Notice that you can access the elements of the container by dereferencing the
iterator.
NOTES: You should prefer pre-increment operator (''++iter'') to post-increment operator (''iter++'')\\
if you are not going to use the old value. \\
Post-increment is generally implemented as follows:
Iter operator++(int)
{
Iter tmp(*this); // store the old value in a temporary object
++*this; // call pre-increment
return tmp; // return the old value
}
Obviously, it's less efficient than pre-increment.
\\
====Iterator Categories====
Not every kind of iterator has exactly the same abilities. Reading and writing require different abilities.\\
Random access is efficient and convenient for a ''vector'', whereas it would be expensive for a ''list''.\\
For this reason, iterators are classified into five categories according to their abilities:
^Iterator Category^Description^Providers^
|input_iterator|Read values with forward movement. These can be incremented, compared, and dereferenced.|istream|
|output_iterator|Write values with forward movement. These can be incremented and dereferenced.|ostream, inserter|
|forward_iterator|Read or write values with forward movement. These combine the functionality of input and output iterators with the ability to store the iterators value.| |
|bidirectional_iterator|Read and write values with forward and backward movement. These are like the forward iterators, but you can increment and decrement them.|list, map, multimap, set, multiset|
|random_access_iterator|Read and write values with random access. These are the most powerful iterators, combining the functionality of bidirectional iterators with the ability to do pointer arithmetic and pointer comparisons.|array, deque, string, vector|
Each of the STL containers is associated with a category of iterator,
and each of the [[stl/algorithm/|STL algorithms]] uses a certain category of iterator.
For example, [[stl/vector/|vectors]] are associated with random-access
iterators, which means that they can use algorithms that require
random access. Since random-access iterators encompass all of the
characteristics of the other iterators, vectors can use algorithms
designed for other iterators as well.
vector the_vector(10);
// generate_n requires output_iterator
generate_n(the_vector.begin(), 5, rand);
// fill requires forward_iterator
fill(the_vector.begin()+5, the_vector.end(), 100);
// random_shuffle requires random_access_iterator
random_shuffle(the_vector.begin(), the_vector.end());
// copy requires input_iterator
copy(the_vector.begin(), the_vector.end(), ostream_iterator(cout, " "));
// reverse_copy requires bidirectional_iterator
reverse_copy(the_vector.begin(), the_vector.end(), ostream_iterator(cout, " "));
\\
====Auxiliary Iterator Functions====
The '''' header file defines two auxiliary functions.
void advance( input_iterator& pos, Dist n );
''advance()'' lets ''pos'' step ''n'' elements forward (or backward).\\
For bidirectional and random_access_iterators, ''n'' can be negative to step backward.\\
For random_access_iterators, ''advance()'' runs in constant time (simply calls ''pos''+=''n'').\\
For all other iterators, ''advance()'' has linear complexity (calls ''++pos'' ''n'' times).
typename iterator_traits::difference_type
distance( input_iterator pos1, input_iterator pos2 );
''distance()'' returns the distance between two iterators.\\
For random_access_iterators, ''distance()'' runs in constant time (simply returns ''pos2'' - ''pos1'').\\
For all other iterators, ''distance()'' runs in linear time ( ''pos1'' is incremented until it reaches ''pos2'', and returns the number of incrementation).
====Invalidating Iterators====
Iterators to exisiting elements in a container can become invalidated when the container is changed. This makes changing the container while iterating it problematic. The containers offer different guarantees in this regard:\\
* vectors: insert/erase can invalidate all iterators.\\
* list/map: erase only invalidates iterators to the erased element(s) & no others.\\
\\
\\
Related topics: [[http://www.oreillynet.com/pub/a/network/2005/10/18/what-is-iterator-in-c-plus-plus.html]]