Well, I'm confused by the whole concept of iterators, really.
Then you should begin by learning iterators in the context of the simplest STL container: a vector.
An "iterator" is something that represents a position in a container. Although it's not exactly correct, you can think of an iterator as a pointer to an element in a container. Hopefully, you know what a pointer is--otherwise all is lost. Then it's just a matter of learning the syntax, which can look a bit frightening, but which is actually fairly easy.
So, let's say you declare a vector and add some elements to the vector, like so:
Code:
vector<int> myVec;
for(int i = 0; i<10; ++i)
{
myVec.push_back(i);
}
Now, you want to output the elements of the vector using an iterator/pointer. First, you have to declare what type of container the iterator/pointer is going to be pointing to. In this case, we want to use an iterator/pointer that points to a vector of int's:
vector<int>
Then you add the member access operator '::',
vector<int>::
Next, you specify the type of iterator you want to use. The simplest iterator is one that allows you to both read and write the vector(just like a normal pointer allows you to both access the value and change the value it points to). The name of such an iterator is simply "iterator" (vs. "const_iterator" which only allows you to read the value it points to, not change it):
vector<int>::iterator
That piece of code specifies the type of the variable you are going to declare--the variable will be a read/write iterator that points to a vector of ints. Now, you need a variable name. How about 'pos' for "position":
vector<int>::iterator pos;
That declares a variable called 'pos' of the specified type. Now you can store an iterator that points to a vector of ints in the variable pos.
Finally, you need to create one of those strange, alien iterators to store in your variable 'pos'. Luckily, we don't have to worry about creating an iterator because all the STL containers have a begin() and end() member function which will create and return an iterator that points to the first or last element respectively. So, you can do this:
vector<int>::iterator pos = myVec.begin();
The result of that statement is that 'pos' will point to the first element in the vector. If you want to "iterate" through all the elements of a vector element by element, you just use '++' on pos to move it from element to element. So, that seems like a good match for a for-loop. To end the for-loop, you can use myVec.end() as the ending condition:
Code:
vector<int>::iterator pos = myVec.begin();
for(; pos != myVec.end(); ++pos)
{
cout<<*pos<<" ";
}
cout<<endl;
A couple of points about that loop:
1) end() returns a pointer to one past the last element
2) Since the loop variable can't be declared succinctly like: int i = 0
you can move the declaration out of the for-loop header and to the line before the for loop(as shown).
3) Use ++pos rather than pos++ because it's more efficient.
4) Since pos is like a pointer to the element, you need to dereference it to get the actual value.
5) When you output a vector's contents, you don't need to change the vector, so it would be better to use
a const_iterator:
Code:
vector<int>::const_iterator pos = myVec.begin();
for(; pos != myVec.end(); ++pos)
{
cout<<*pos<<" ";
/*pos = 10; error*/
}
cout<<endl;
As far as maps are concerned, you need to know what a pair<> is to use them effectively. In a map, all the elements of the container are single entities, just like with a vector. However, each entity in a map is what's called a pair<>, and each pair<> contains two elements: the key and the value. A pair<> contains the key in a member variable called 'first', and a pair<> contains the value in a member variable called 'second'. Here is an example:
Code:
map<string, int> stringIntMap;
stringIntMap.insert( make_pair( string("john"), 31) );
stringIntMap.insert( make_pair( string("jane"), 18) );
stringIntMap.insert( make_pair( string("betty"), 35) );
map<string, int>::iterator pos = stringIntMap.begin();
for(; pos != stringIntMap.end(); ++pos)
{
cout<<pos->first<<" "<<pos->second<<endl;
}
Note: a string literal(i.e. something between double quotes) is a char array and not a string type, so on my compiler I have to use the string constructor to convert a string literal to a string type.