|

Iterators are STL
objects that represent
the positions of
elements in various STL containers. They serve
a function
similar
to that of a subscript in a C++ array, permitting
the programmer to access a particular element, and
to
"iterate" through the container. An iterator object is always associated
with one specific type of container object.
Therefore, its type
depends on the type of the container. Example:
#include <list>
#include <vector>
using namespace std;
list<int> nums;
list<int>::iterator nums_iter;
vector<double> values;
vector<double>::iterator values_iter;
vector<double>::const_iterator const_values_iter;
|
Types of iterators: Forward - specifies the position of a single
element in a container. Moves in one direction from
element to element.
Bidirectional - like a forward iterator, but moves in two directions,
forward and reverse, from element to element.
Random Access - like a bidirectional iterator, but
can also move in larger steps, skipping
multiple elements.
Iterator operators:
Overloaded iterator operators are:
==, !=, *, ++, --, +=, -=, +, -, <, >, <=, >= .
Let's look at an example: Below, after creating a
list of integers and adding some elements, we
initialize the iterator
nums_iter
to specify the first list position,
nums.begin().
The loop runs until we reach the iterator value that
represents the position just beyond the last list
element,
nums.end().
Each list element is
accessed by the "*" operator, which returns
a reference to the element. The increment operator (++)
moves the iterator to the next position in the list.
In this case, we are using the iterator to modify the list
elements. If this were not so, the iterator could have
been declared constant, like:
list<int>::const_iterator
nums_iter; .
#include <iostream> #include <list>
using namespace std;
void main() {
list<int> nums;
//Declare an iterator
list<int>::iterator nums_iter;
nums.push_back(100);
nums.push_back(200);
nums.push_front(300);
cout << endl << "List 'nums' now becomes:" << endl;
for(nums_iter = nums.begin(); nums_iter != nums.end(); nums_iter++)
{ //We must dereference the iterator since we are modifying object values rather than addresses
*nums_iter = *nums_iter + 3;
cout << (*nums_iter) << endl;
}
cout << endl; } //close main() |
Output:
List 'nums' now becomes: 303 103 203 |
When the elements stored in an STL
container are objects of a class type,
we may want to invoke member functions of the object
referenced by an iterator. If doing so, we
must bear in mind operator precedence. Example:
#include <iostream> #include <list>
#include <string>
using namespace std;
void main() {
list<string> words;
//Declare iterator
list<string>::iterator words_iter;
unsigned int total_length = 0;
for(words_iter = words.begin(); words_iter != words.end(); words_iter++)
{ //We must dereference the iterator to get at the value first
total_length += (*words_iter).length(); // correct
// total_length += *words_iter.length(); // incorrect !!
}
cout << "Total length is " << total_length << endl;
} // close main() | | Output: Total length is 0 |
In the example
above, the parentheses around "*words_iter" are
required when we invoke the "length()" member
function. Without them, the compiler would think
that the "length()" function is a member of the
iterator class, rather than the string class, since the
"." operator would be evaluated before the
unary "*" operator. As you might expect, the parentheses would also
be required if we wish to access a data member of an
object referenced by an iterator.
Some STL functions (algorithms and container member
functions) require iterator arguments:
- The
sort algorithm, when applied
to a
vector container.
- The erase
member function,
specifying one element or a range of elements,
with vector
and
list containers.
- The
find algorithm, when applied
to a
list container.
#include <iostream> #include <vector>
#include <list>
#include <algorithm>
using namespace std;
void main() {
vector<int> vect1;
int num1 = 10; int num2 = 5;
vect1.push_back(num1); vect1.push_back(num2); vect1.push_back(20); vect1.push_back(15);
vector<int>::iterator IntIterator;
//----------------------------------------------------------------------------------------------------------------------
//Before sort cout << "Here\'s the contents of the vector before sort:\n"; for(IntIterator = vect1.begin(); IntIterator != vect1.end(); IntIterator++) { cout << (*IntIterator) << endl; } cout << endl;
//----------------------------------------------------------------------------------------------------------------------
//After sort cout << "Here\'s the contents of the vector after sort:\n"; sort(vect1.begin(), vect1.end()); for(IntIterator = vect1.begin(); IntIterator != vect1.end(); IntIterator++) { cout << (*IntIterator) << endl; } cout << endl;
//----------------------------------------------------------------------------------------------------------------------
//Using find(), searching for 15 cout << "Callling find(). Searcing for 15." << endl; IntIterator = find(vect1.begin(), vect1.end(), 15); if(IntIterator != vect1.end()) { cout << "Number " << (*IntIterator) << " was found." << endl; } else { cout << "Number not found." << endl; } cout << endl;
//----------------------------------------------------------------------------------------------------------------------
//Using find(), searching for 100 cout << "Callling find(). Searcing for 100." << endl; IntIterator = find(vect1.begin(), vect1.end(), 100); if(IntIterator != vect1.end()) { cout << "Number " << (*IntIterator) << " was found." << endl; } else { cout << "Number not found." << endl; } cout << endl;
//----------------------------------------------------------------------------------------------------------------------
//Calling erase() cout << "Here\'s the contents of the vector after erase():\n"; vect1.erase(vect1.begin(),vect1.end()); for(IntIterator = vect1.begin(); IntIterator != vect1.end(); IntIterator++) { cout << (*IntIterator) << endl; } cout << endl;
//----------------------------------------------------------------------------------------------------------------------
} //close main() |
Output:
Here's the contents of the vector before sort: 10 5 20 15
Here's the contents of the vector after sort: 5 10 15 20
Callling find(). Searcing for 15. Number 15 was found.
Callling find(). Searcing for 100. Number not found.
Here's the contents of the vector after erase(): |
©2004 C. Germany
|