Boost logo

Boost :

From: Richard Smith (richard_at_[hidden])
Date: 2006-07-13 05:02:45


David Abrahams wrote:

> Richard Smith <richard_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk