In order to traverse grids with data in a fast and flexible way I set up an abstract, templated GridDataStructure class. The data should be accessed by STL iterators. When someone uses the class, he should not worry about which kind of STL iterator is appropriate for a specific subclass.
A solution to this problem seems to be http://stackoverflow.com/questions/2191724/using-iterators-to-hide-internal-container-and-achieve-generic-operation-over-a-b. However, I do not get why the begin() and end() members are not virtual anymore. Next to that I could not figure out where exactly the necessary methods for the STL iterator class (like operator++, operator* etc.) should be implemented.
Could you please have a look whether or not I make a design mistake? Important to me is a flexible design, but not at the cost of performance.
My class design:
template<class T>
class GridDataStructure
{
public:
virtual iterator begin() = 0;
virtual iterator end() = 0;
};
template<class T>
class GridDataUniform : GridDataStructure
{
public:
GridDataUniform(int size);
iterator begin();
iterator end();
class iterator : public std::iterator<std::forward_iterator_tag, T> {
public:
iterator(Node* p) : node_(p) {}
~iterator() {}
iterator& operator=(const iterator& other);
bool operator==(const iterator& other);
bool operator!=(const iterator& other);
iterator& operator++();
iterator& operator++(int);
T& operator*();
T* operator->();
private:
Node* node_;
};
private:
T* griddata;
};
I would like to access my grid container in STL style, like:
GridDataStructure<int>::iterator = someGrid->begin(); // where someGrid is an instance of GridDataUniform
std::cout << *(iter) << std::endl;
Any help is highly appreciated.
Edit (19.10.10): Added nested iterator class
Edit (20.10.10): Added code:
template<class T>
class GridDataStructureBase
{
protected:
class BaseIteratorImpl
{
virtual iterator begin() = 0;
virtual iterator end() = 0;
virtual iterator& operator++() = 0;
}
public:
class iterator : std::iterator<std::forward_iterator_tag, T>
{
public:
iterator(const BaseIteratorImpl& itImpl) {}
iterator begin() { return itImpl->begin(); }
iterator end() { return itImpl->end(); }
iterator& operator++() { return itImpl->operator++() }
private:
BaseIteratorImpl* itImpl;
};
iterator begin()
{
iterator* i = new iterator(??);
return i->begin();
}
iterator end()
{
return iterator(NULL);
}
};