I'm implementing an iterator for an adaptor range which lazily evaluates something on an original range. This means: dereferencing the iterator should dereference the underlying iterator and apply some operation on the result, then returning the result of that operation.
T operator*() const {
return someOperation(*original_iterator);
}
How can I implement operator->
analogous to this operator*
? When looking at other iterator's implementations, they usually return a T*
. But I can't return a pointer, since the "pointed to object" is a temporary, computed on-the-fly.
What's the usual guidance in this case? May I simply return a T
instead?
Although I personally don't need this operator (I could also use (*i).m
instead of i->m
and the standard algorithms don't seem to depend on ->
either), I'd like my iterator to strictly conform to the ForwardIterator
concept which is a specialization of InputIterator
which requires the implementation of this operator.
The simplest way is to just use Boost.Iterators to implement your iterators, which takes care of the tricky code.
But the technique used by Boost.Iterators isn't that complicated. It looks like this:
template <typename T>
class proxy_holder {
T t;
public:
proxy_holder(const T& t) : t(t) {}
T* operator ->() const { return &t; }
};
class the_iterator {
// ...
proxy_holder<my_proxy> operator ->() const {
return proxy_holder<my_proxy>(**this);
}
};
This relies on the fact that arrow operators get chained, i.e. if one arrow operator returns something that isn't a raw pointer, the arrow operator is called on that thing in turn, until you get to a pointer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With