Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a c++ function what can return either iterator or reverse_iterator

Tags:

c++

iterator

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...

like image 578
Sideshow Bob Avatar asked Jul 15 '11 13:07

Sideshow Bob


People also ask

What is the use of iterators in c++?

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.

How to define reverse iterator in c++?

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.

What is used to return a reverse iterator to the end of the container for iterating backward through the container?

rbegin() return an iterator with a reverse operator++ ; that is, with a reverse_iterator you can iterate through a container going backward.

How to iterate set in reverse?

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.


1 Answers

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;
};
like image 58
Mark Ransom Avatar answered Sep 21 '22 02:09

Mark Ransom