Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a bidirectional iterator for a class

Tags:

c++

I have a class that holds strings. Basically the class is built on an array of strings:

class stringlist {
public:
    typedef std::string str;
    void push(str);
    void pop();
    void print();
    void resize(size_t);
    size_t capacity();
    size_t size();
    stringlist() : N(15) {}
    stringlist(size_t sz) : N(sz) {}
    ~stringlist() { delete [] container; }
}
private:
    size_t N;
    str* container = new str[N];
};

The next part of the exercise asks readers to

Write a bidirectional iterator for your class

At this point in the book, there is no talk of overloaded operators etc.

If I have something like str* iterator(*str), how would I manage incrementation, decrementation, etc. I am assuming I can write a separate function for these methods but that seems like it would defeat the purpose of writing a iterator data member in the first place. Would the iterator be a separate class?

Also, would it be possible to have the increment decrement functions inside the iterator so that I can dot into the iterator to use these functions?

like image 833
Mars Avatar asked Nov 06 '13 16:11

Mars


People also ask

What is a bidirectional iterator?

A Bidirectional Iterator is an iterator that can be both incremented and decremented. The requirement that a Bidirectional Iterator can be decremented is the only thing that distinguishes Bidirectional Iterators from Forward Iterators.

What is a bidirectional iterator C++?

Iterators are a generalization of pointers that allow a C++ program to uniformly interact with different data structures. Bidirectional iterators can move both forwards and backwards through a container, and have the ability to both read and write data.

Is iterator a class in C++?

An iterator is an object that can iterate over elements in a C++ Standard Library container and provide access to individual elements.

Is map iterator bidirectional?

map::iteratorThe type describes an object that can serve as a bidirectional iterator for the controlled sequence. It is described here as a synonym for the implementation-defined type T0 .


1 Answers

A pointer is a valid bidirectional iterator. (It is also random-access)

So you can add iterator support to your class with

typedef str* iterator;
typedef const str* const_iterator;
iterator begin() { return container; }
const_iterator begin() const { return container; }
iterator end() { return begin() + size(); }
const_iterator end() const { return begin() + size(); }
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }

However, you can't use pointers to implement reverse iteration (which uses ++ to go backwards, and -- to go forwards). But the Standard library provides a nice adaptor (in #include <iterator>):

typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
const_reverse_iterator crbegin() const { return rbegin(); }
const_reverse_iterator crend() const { return rend(); }
like image 182
Ben Voigt Avatar answered Sep 26 '22 15:09

Ben Voigt