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 someo
In the solution, begin and end don't need to be virtual, because they just call BaseIteratorImpl::begin
and BaseIteratorImpl::end
which are virtual.
In your specific case, you could just make begin
and end
virtual and not do any forwarding and it would be able to do what you want. The solution you pointed to is if you want different style iterators over the same structure, not just structure-iterator pairings which it seems you want.
EDIT: Here's something to start with (not tested or even compiled) -- might not compile and will leak (write destructors, copy ctors, op=, where you need to) -- just to get you started on the idea.
template <class T>
class GridIteratorImplBase {
public:
virtual GridIteratorImplBase<T>& operator++() = 0;
virtual T& operator*() = 0;
};
template <class T>
class GridIterator {
private:
GridIteratorImplBase<T> *baseImpl;
public:
GridIterator(GridIteratorImplBase<T> *b) :baseImpl(b) {}
GridIterator& operator++() { baseImpl->operator++(); return *this;}
T& operator*() { return baseImpl->operator*(); }
// you need to write a dtor, copy ctor and op= or this will leak
// copy ctor and op= need to make new objects that are copies of baseImpl, dtor needs to delete -- make sure not to share baseImpl between two GridIterator objects
};
template <class T>
class Grid {
virtual GridIterator<T> begin() = 0;
virtual GridIterator<T> end() = 0;
};
template <class T>
class GridUniform {
template <class T>
class GridUniformIterator : GridIteratorImplBase<T>
private T* current;
public:
GridUniformIterator(T* c) : current(c) {}
virtual GridIteratorImplBase<T>& operator++() { current++; return *this; }
virtual T& operator*() { return *current; }
};
GridIterator<T> begin() {
GridIterator<T> iter(new GridUniformIterator(gridData));
return iter;
}
GridIterator<T> end() {
GridIterator<T> iter(new GridUniformIterator(gridData+size));
return iter;
}
private:
T* gridData;
int size;
};
I typed this directly in to the text area of this answer -- not a compiler. It's meant to give you the idea so you can get started.