Belebele wrote:
Quote:
I have an Element class which is abstract and I would like to have an
object of the Iterator class to iterate over a range of elements.
>
I would like to use std::for_each to instrument the iteration, which
forces me to have certain interface on the Iterator class.
>
struct Element {
virtual ~Element() = 0;
};
>
struct Iterator {
bool operator!=(Iterator const& ) const;
Iterator& operator++();
>
// The returned value of this function is the motivation of my
post
// Please, see the comments below the code.
Element& operator*() const;
};
>
struct Range {
Iterator begin() const;
Iterator end() const;
};
>
>
and the client code:
>
void action(Element const& );
void main()
int main()
Quote:
{
Range range;
std::for_each(range.begin(), range.end(), action);
}
>
>
Now, after reading some earlier posts, I get the impression that
experience dictates that iterators should return objects by value.
Oh, what nonsense! Now you're falling into another extreme. First,
your iterator owned the object and returned a reference to it upon
request, but then the reference would become invalid as soon as the
iterator moves onto the next object (which prompted me to suggest
retuning an object instead). Now, the object is actually owned by
the "Range", and there is no concern about the validity of the
reference returned by the iterator. So, return a reference. It's
going to be valid as long as the Range where the object lives keeps
it valid. IOW, disconnect the object and the iterator. Only have
the connection between the iterator and the container it traverses.
Quote:
[..]
>
Any comments?
If your "Iterator" is specific to your "Range", you should make
the Iterator class a nested class in Range, most likely. Thus
a semantic relation will be established and the design intent will
be very clear.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask