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::pair
s 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?
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.
精彩评论