Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overload operator-> on a "generating" iterator?

I'm defining an iterator type that does not store its current value explicitly. Instead, it's a wrapper around another iterator, and returns std::pairs of the underlying iterator's values and another value. The relevant part of the class definition:

class MyIterator : public std::iterator<input_iterator, std::pair<Foo *, Bar *> > {

    FooPtrIterator d_iter;
    Bar d_bar;

    public:

        MyIterator(FooPtrIterator iter, Bar const &bar)
        :
            d_iter(iter),
            d_bar(bar)
        { }

        // Returning by value, not storing the pair itself.
        value_type operator*() const {
            return std::make_pair(*d_iter, &d_bar);
        }

        // Can't return by value!
        ??? operator->() const {
            return ???;
        }

};

Now this gets me in trouble when overloading operator->, because I'm expected to return a pointer, or something else that itself supports operator->.

I could simply store the current std::pair as a class member:

    value_type d_current;

However, that gets me in trouble in the constructor, because I cannot know at that point whether FooPtrIterator iter is a valid iterator, so I cannot dereference it to provide d_current with a value.

I can also make operator-> return a boost::shared_ptr<value_type> but that is a terrible hack with more overhead than should be needed.

I get the feeling that this "generating" iterator is not supposed to exist. Is that so, or is there another way around this?

like image 323
Thomas Avatar asked Jan 19 '26 08:01

Thomas


1 Answers

I would suggest creating an own class holding the Foo* and Bar* pair, like this:

class MyPair  {
private:
  FooPtrIterator foo;
  Bar bar;

public:
  MyPair(const FooPtrIterator& it, const Bar& b) : foo(it), bar(b)  {}

  Foo* first() { return *foo; }
  Bar* second() { return &bar; }
};

Then just use it inside your iterator class instead of the two values. You will have to change ->first and ->second to ->first() and ->second() in your code but that should be an acceptable change.

like image 168
Karel Petranek Avatar answered Jan 21 '26 23:01

Karel Petranek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!