Writing Iterators
Iterators
Often times, we need to loop over all elements in the "container".
Code to "run through all elements" can look very different for different containers.
cur
pointer that advances through a linked list vs. afor
loop over integer indices of a vector.
C++ iterators unify these different code segments.
- Regardless of the container specifics, an iterator feels like a pointer to successive individual elements, that we can easily advance.
There are many different iterators with different types provided for
the container class
es in STL.
Defining Custom Iterators
If we make our own container class from scratch to represent, say, a deck of cards, it would be nice to have an iterator for the deck.
We define an entirely new class to represent an iterator.
- Write our own
iterator
(orconst_iterator
orreverse_iterator
) as a nested class inside the container class (that's why you always use the::
to access iterators). - A nested class sits inside another class definition, and has access to the members of the enclosing
class, including
private
members.- Each
iterator
class simply wraps a layer ofoperator
overloads around a pointer.
- Each
Suppose we want to output the elements in MyContainerType c
, we use the iterator
in this way:
for (MyContainerType::iterator it = c.begin(), c != c.end(); ++it) {
//*it can now be used to refer to each successive element
std::cout << *it < " ";
}
Therefore we need to overload the
- inequality operator (
operator!=
) - dereference operator (
operator*
) - preincrement operator (
operator++
)
A real world iterator
might also overload:
- equality operator (
operator==
) - arrow operator /
class
member access operator (operator->
)
In addition to overload these operators, the enclosing (containing
) class
(MyContainerType
) should also define methods named begin
and end
,
which return iterators
to the first item in the collection, and the just-past-last element in
the collection, respectively.
- If you are defining a
const_iterator
, it should havecbegin
,cend
, and a different overloadedoperator*
. Similarly forreverse_iterator
, haverbegin
,rend
, and a different overloadedoperator++