arrow operator (operator->) return type when dereference (operator*) returns by value

template<class T>
struct fake_ptr_with_value {
  T t;
  T* operator->() { return std::addressof(t); }
};

return a fake_ptr_with_value<decltype(**this)>.

No such helper type is exposed from std.

Please note that due to defects in the specifications of what various iterator classes require, this is only usable for InputIterators. Forward iterators (and all more powerful iterators, like random access iterators), under the standard, require that operator* return a reference to a true and stable object.

The defect is that the standard (a) in some cases requires references when pseudo-references would do, (b) mixes "iteration" and "dereference" semantics.

Rangesv3 has a more decoupled iterator category system that addresses some, if not all, of these defects.

As this question is about input iterators, this solution is sufficient; I am just including this caution in case someone wants to use this technique elsewhere. Your code may compile and seem to work, but you are almost certainly going to be violating the requirements of the C++ standard when you pass your iterator to any std function, which means your program is ill-formed no diagnostic required.


Since -> will continue "drilling down" until it hits a pointer return type, your code could return a "proxy" for the pair with the pair embedded in it:

template<class T1, class T2>
class pair_proxy {
    std::pair<T1,T2> p;
public:
    pair_proxy(const std::pair<T1,T2>& p) : p(p) {}
    std::pair<T1,T2>* operator->() { return &p; }
};

Note: I would strongly consider embedding std::pair in your iterator, and returning a pointer to it from your operator ->() implementation.

Tags:

C++

Iterator