views:

58

answers:

1

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?

+1  A: 

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.

dark_charlie
This is a good solution, and as simple as it gets. Thanks!
Thomas