
Christian Engström <christian.engstrom@glindra.org> writes:
David Abrahams wrote:
Christian Engström <christian.engstrom@glindra.org> writes:
A proxy_iterator is publicly derived from the iterator of the underlying Container< proxy<T> >.
And if that iterator happens to be a pointer?
Then of course it doesn't work. But is the container really STL compliant if it has ordinary pointers as iterators?
Yes. Many std::vector implementations do that.
If the answer to this question is yes, the requirement that the underlying iterator type must be a class should of course be added to the documentation, but apart from that I see no problem with it.
Are we really allowed to define these operators like this? --Yes, we are. No you're not. The standard makes it very clear that the semantics of an iterator's operator-> must correspond to those of its operator*.
Or else what?
Or else the class doesn't satisfy the iterator requirements.
Is there anything particular that the standard says will break if the two operators have different semantics?
Technically, anything that claims to depend on a parameter matching the iterator concept. Less, technically, any generic algorithm that takes advantage of an iterator's operator->. The fact that the ones in the standard library don't use operator-> doesn't mean very much, since other peoples' algorithms are allowed to rely on iterators matching the standard iterator requirements.
In Bjarne Stroustrup's "The Design and Evolution of C++", he says on page 241 (in the edition that I have):
"For ordinary pointers, use of -> is synonymous with some uses of unary * and []. For example, for a Y* p it holds that: p->m == (*p).m == p[0].m As usual, no such guarantee is provided for user-defined operator. The equivalence can be provided when desired: [...]"
The way I read it, the phrase "can ... when desired" does not have the same meaning as "must always". Am I misunderstanding something or is Bjarne Stroustrup wrong?
Sure you can do whatever you want. You just can't call it an iterator (in C++). The standard library defines what an iterator is.
The design makes several other wrong assumptions about iterator requirements.
If you or somebody else can point them out to me I shall be very grateful.
I don't have time to look for all of them, but one assumption it makes is that the underlying iterator supplies value_type, iterator_category, etc. via nested public types as opposed to a specialization of std::iterator_traits. Writing correct iterators is really hard; that's part of the reason for the boost iterators library.
indirect_iterator may already suit your needs.
Does indirect_iterator make possible to convert a program that has been written to use a direct container to use an indirect container instead by changing a single typedef?
Not by itself, but it does most of the work for you. -- Dave Abrahams Boost Consulting www.boost-consulting.com