From: Peter Dimov (pdimov_at_[hidden])
Date: 2002-08-24 07:49:37
From: "Gabriel Dos Reis" <gdr_at_[hidden]>
> Andrew Koenig <ark_at_[hidden]> writes:
> | David> I don't think that's the real question at all.
> | David> The problem is that the return type of operator can't be relied
on to be
> | David> a reference, and in particular you can't do
> | David> p[n] = x;
> | David> with a generic random-access iterator.
> | David> *(p + n) = x;
> | David> always works (for sufficiently correct values of n and x).
> | Interesting -- I wonder why I never noticed that?
> | One would think that p[n] should be equivalent to *(p+n) -- in
> | it should be required to have the same type.
> The random access iterator requirements table 76 says that p[n] as the
> "operational semantics" "*(p + n)".
We already went over this with Dave, but:
True, p[n] has the operational semantics of *(p + n), but it's not the same
as *(p + n), since *(p + n) is required to return a reference, whereas p[n]
is only required to return something "convertible to T".
The reason for this is that in
void f(value_type &);
f(*(p + n));
the temporary "p + n" is guaranteed to live until the end of the full
expression, and *(p + n) may return a reference to something inside that
p[n] cannot return *(p + n) by reference, since the p + n temporary will
disappear and the result would be a dangling reference.
That's why p[n] is specified to be "convertible to T" - to allow a proxy
with operator T() / operator=(T const &) to be returned.
In practice, this means that p[n] should never be used.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk