I'm implementing STL containers, for example, vector. What confused me is the implementation of iterators.
If I want to implement all iterator categories: input_iterator, output_iterator, forward_iterator, bidirectional_iterator and random_access_iterator.
How do I manage their inheritance relationships? I've read How to implement an STL-style iterator and avoid common pitfalls?-Mooing Duck's Answer
This is his example symbolic:
iterator {
iterator(const iterator&);
~iterator();
iterator& operator=(const iterator&);
iterator& operator++(); //prefix increment
reference operator*() const;
friend void swap(iterator& lhs, iterator& rhs); //C++11 I think
};
input_iterator : public virtual iterator {
iterator operator++(int); //postfix increment
value_type operator*() const;
pointer operator->() const;
friend bool operator==(const iterator&, const iterator&);
friend bool operator!=(const iterator&, const iterator&);
};
//once an input iterator has been dereferenced, it is
//undefined to dereference one before that.
output_iterator : public virtual iterator {
reference operator*() const;
iterator operator++(int); //postfix increment
};
//dereferences may only be on the left side of an assignment
//once an input iterator has been dereferenced, it is
//undefined to dereference one before that.
forward_iterator : input_iterator, output_iterator {
forward_iterator();
};
//multiple passes allowed
bidirectional_iterator : forward_iterator {
iterator& operator--(); //prefix increment
iterator operator--(int); //postfix decrement
};
random_access_iterator : bidirectional_iterator {
friend bool operator<(const iterator&, const iterator&);
friend bool operator>(const iterator&, const iterator&);
friend bool operator<=(const iterator&, const iterator&);
friend bool operator>=(const iterator&, const iterator&);
iterator& operator+=(size_type);
friend iterator operator+(const iterator&, size_type);
friend iterator operator+(size_type, const iterator&);
iterator& operator-=(size_type);
friend iterator operator-(const iterator&, size_type);
friend difference_type operator-(iterator, iterator);
reference operator[](size_type) const;
};
But I found a problem:
If I have an instance a
from class random_access_iterator
, I use the code random_access_iterator b = a + 1
. This will cause compile error. Because a + 1
's class is base iterator
, not random_access_iterator
.
So I don't think this is a reasonable solution.
Do I misunderstand it? Or please tell me an elegant and efficient way to implement it.
Thanks