As far as I can tell in c++ there is no common base class that covers both iterator and reverse_iterator.
The only suggestion I have seen so far is to get around this using templates ( How to write a function that takes an iterator or collection in a generic way? )
However this solution doesn't seem to work for me.
class MyClass
{
template<typename Iter> Iter* generate_iterator(...params...)
{
//returns either a vector::iterator or vector::reverse_iterator
}
template<typename Iter> void do_stuff(Iter *begin, Iter *end)
{
//does stuff between elements specified by begin and end
//I would like this function to remain agnostic of which direction it is working in!
}
void caller()
{
//I would like this function to remain agnostic of which direction it is working in too...
do_stuff(generate_iterator(blah),generate_iterator(foo));
}
};
In this case, generate_iterator() cannot be used as desired because the compiler complains "generate_iterator is not a member of class MyClass" presumably because I haven't specified it (which I can't in practice as caller should be agnostic of the iterator type).
Can anyone help? Thanks in advance!
edit: as Mark B pointed out generate_iterator must return a pointer - now corrected
update: just started using this http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/start_page.html and it seems to work...
An iterator is used to point to the memory address of the STL container classes. For better understanding, you can relate them with a pointer, to some extent. Iterators act as a bridge that connects algorithms to STL containers and allows the modifications of the data present inside the container.
C++ Iterators Reverse IteratorsA reverse iterator is made from a bidirectional, or random access iterator which it keeps as a member which can be accessed through base() . To iterate backwards use rbegin() and rend() as the iterators for the end of the collection, and the start of the collection respectively.
rbegin() return an iterator with a reverse operator++ ; that is, with a reverse_iterator you can iterate through a container going backward.
Approach: To traverse a Set in reverse order, a reverse_iterator can be declared on it and it can be used to traverse the set from the last element to the first element with the help of rbegin() and rend() functions. Get the set. Declare the reverse iterator on this set.
You can create your own iterator class that knows how to go both directions. Encapsulate both types of iterator and internally select whichever one you were initialized with.
Here's a start:
template<typename Container>
class BiIterator
{
public:
BiIterator(Container::iterator i) : m_fwd(i), m_isforward(true) {}
BiIterator(Container::reverse_iterator i) : m_rev(i), m_isforward(false) {}
bool operator==(const BiIterator & left, const BiIterator & right);
Container::value_type & operator*()
{
if (m_isforward)
return *m_fwd;
return *m_rev;
}
const Container::value_type & operator*() const;
BiIterator & operator++()
{
if (m_isforward)
++m_fwd;
else
++m_rev;
return *this;
}
private:
Container::iterator m_fwd;
Container::reverse_iterator m_rev;
bool m_isforward;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With