
David Abrahams wrote:
Richard Smith <richard@ex-parrot.com> writes:
[...]
it is legal to call non-const member functions on the value returned from operator*:
struct foo { void non_const(); };
my_iterator<foo> i; (*i).non_const();
No. The value returned from operator* might be a const proxy with a (const) conversion operator to value_type.
That's an interesting point. If operator* returns a proxy type, as operator. cannot be overloaded, (*a).m will always call a member of the proxy type, so for a->m to be equivalent, the operator-> should return (probably by proxy) a pointer to the operator* proxy type. I.e. template <typename T> struct it { typedef T value_type; struct value_proxy { operator value_type() const; }; typedef const value_proxy reference; reference operator*() const; struct arrow_proxy { reference* operator->() const; }; arrow_proxy operator->() const; }; So assuming the reference typedef is precisely the return type of operator* (including top-level constness), if it is a real reference, we don't need an arrow_proxy, and if it's a value, arrow_proxy should always act as reference*, even when the reference typedef is itself a proxy. Does that sound right? (The only examples of proxy types returned from operator* that I can think of are things like vector<bool>::reference, where value_type has no members and so operator-> is irrelevant. I imagine in the absense of an overloadable operator., that's all you can do.)
My reading of Table 72 documentation suggests that this means that for my_iterator<foo> to be a Readable Iterator,
Table 72 doesn't describe Readable Iterator.
Sorry, I meant Input Iterator or the equivalent table in the "New Iterator Concepts" paper for Readable Iterator.
it must also be legal to write:
i->non_const();
All Table 72 says about operator-> is
a->m precondition: (*a).m is well-defined Equivalent to (*a).m
Yes. I was meaning where i was still the specific my_iterator<foo> defined earlier, in which case I think it does imply that. But I think you're agreeing with me below.
If so, this means that operator-> should return T* instead of T const* (possibly via a proxy class).
If operator* returns value_type, I think I agree that operator-> should return T* or an equivalent proxy pointer.
I think more generally (as discussed above), if operator* returns any cv-qualified non-reference type, T, that operator-> should return T* or an equivalent proxy pointer.
Please enter a bug report at SourceForge so this doesn't get lost.
Will do. Thanks, Richard