问题
I have a template based custom collection (as we cannot use std::vector on the interface). I would like to implement a reverse_iterator specific to this collection. The reverse iterator struct below is a structure nested within the collection class. An iterator (basically a pointer to element type of the collection) is already implemented. This is my first attempt at a reverse iterator.
template <typename T>
struct reverse_iterator
{
typedef T::iterator iterator;
typedef T& reference;
inline reverse_iterator(const iterator & it):_it(it){}
inline reverse_iterator() : _it(0x0) {}
inline iterator base() const {iterator it = _it; return --it;}
inline reverse_iterator operator ++ () {return reverse_iterator(--_it);}
inline reverse_iterator operator -- () {return reverse_iterator(++_it);}
inline reverse_iterator operator ++ (int val) {_it -= val; return reverse_iterator(_it);}
inline reverse_iterator operator -- (int val) {_it += val; return reverse_iterator(_it);}
inline reverse_iterator operator += (int val) {_it -= val; return reverse_iterator(_it);}
inline reverse_iterator operator -= (int val) {_it += val; return reverse_iterator(_it);}
inline reverse_iterator operator + (int val) const {iterator it = _it - val; return reverse_iterator(it);}
inline reverse_iterator operator - (int val) const {iterator it = _it + val; return reverse_iterator(it);}
bool operator == (const iterator & other) const {return other == base();}
bool operator != (const iterator & other) const {return other != base();}
reference operator*() const {return *base();}
iterator operator->() const {return base();}
private:
iterator _it;
};
- Is this is workable reverse_iterator or am I missing something ?
- Can this be improved?
回答1:
Except for the things mentioned below your implementation is almost the same as the implementation in libstdc++ (v3, but still somewhat accurate). Note that you're currently missing all non-member functions. All in all you should try to match the std::reverse_iterator interface: if you're ever able to use std types you can happily exchange your mylab::reverse_iterator
by std::reverse_iterator
.
Missing things
- You're missing all comparison operators between
reverse_iterator
, such asoperator==
,operator!=
,operator<
and so on.
Strange things
This is basically a list of stuff where your reverse_iterator
differs from the standard one.
Usually the pre-increment/-decrement operators return a reference (
*this
) and not a new object.The post increment/decrement operators shouldn't take a value:
inline reverse_iterator operator ++ (int) { reverse_iterator tmp = *this; ++*this; // implement post-increment in terms of pre-increment! // or --_it; return tmp; } inline reverse_iterator operator -- (int) { ... }
The compound assignment operators also usually return references.
- Your
const iterator&
constructor should beexplicit
, otherwise one could accidentally mix reverse and normal iterators. Instead of a container type
T
you should use the underlying iterator as template parameter:template <typename Iterator> struct reverse_iterator { typedef Iterator iterator; typedef typename iterator_traits<Iterator>::reference reference; ... }
This enables you to use
reverse_iterator
on anything thatiterator_traits
can handle:template <class Iterator> struct iterator_traits{ typedef typename Iterator::reference reference; // Add other things }; template <class T> struct iterator_traits<T*>{ typedef T & reference; };
With this you can even use
reverse_iterator<int *>
or similar.operator->
usually returns a pointer to the underlying object, not an intermediary iterator. You might want to add apointer
typedef to both your traits and your original iterator.- It's very uncommon to check equality between different types. Remove the
operator==(const iterator&)
.
来源:https://stackoverflow.com/questions/21275190/c-custom-collection-reverse-iterator-with-similar-behaviour-to-stdvector-imp