I have a question about implementing a shared iterator interface.
As common practice for postix operator the function might look like this:
IteratorClass operator ++(int) {
IteratorClass temp = *this;
//increment stuff
return temp
}
And most of the time this is fine. In my case I am trying to implement 3 iterators for one class. Each iterator will load a local collection class with data but each derived iterator would load it in a different way. Because the collection class would be the same and all of the code for the operators( postfix/prefix ++/--, *) would be the same I thought a nice way to implement this would be inheritance:
struct iterator {
protected:
Collection collection;
public:
operator++(int);
operator++;
operator--(int);
operator--;
virtual load() = 0;
}
struct iterator1 : public iterator {
virtual load() { custom load function }
}
struct iterator2 : public iterator {
virtual load() { custom load function }
}
The problem are the postfix operators... They are trying to create an object of an abstract type and then returning it. Any suggestions for workarounds or structure changes?
Use the CRTP idiom to make the base class aware of the final class. For example:
template<typename T>
struct iterator_base {
public:
T operator++(int) {
T temp = static_cast<T&>(*this);
++*this;
return temp;
}
T& operator++() {
// ++ mutation goes here
return *this;
}
// ... likewise for --, etc.
};
struct iterator1: public iterator_base<iterator1> {
// ... custom load function
};
This approach is called static polymorphism, and allows you (in some cases) to completely eschew virtual
and therefore make your objects smaller. You can omit the load
declaration from the base classes and call T::load
as static_cast<T&>(*this).load()
.
来源:https://stackoverflow.com/questions/18172858/c-abstract-base-class-postfix-operator