The method end() does not return an lvalue, the code would not
compile if the iterator happens to be a pointer.
Or if it's a classe type with a global operator-- (probably a
friend).
Generally, I would avoid code that renders T* a non-model for
a iterator to T. This way, I keep my code more generic. Of
course, there is no real harm in cases where you know that the
iterator is of class type.
That's not true, since the standard doesn't require operator--
to be a member. (If it's not a member, it rather obviously
takes a non-const reference, so you can't bind a temporary to
it.)
In general, I would argue that in a quality implementation,
overloaded operators which require lvalues should be
non-members, taking a non-const reference, so that the
overloaded operator also requires an lvalue. In practice,
however:
I think that this point has only been realized very, very
recently. All of the implementations of the standard
library I know date to well before I realized it, in any
case. So they don't follow this rule, and you can't fault
them for not following a guideline which didn't exist when
they were written.
The most frequent user defined operator which requires an
lvalue is simple assignment. And you can't make that one a
non-member. Given that you're already forced to compromize
in the most frequent case, I'm not sure that it's worth the
bother in the other cases. If it's no more effort to make
the operator a global function (and in the case of compound
assignment operators, it's often significantly less effort),
go ahead and do it, but it's not worth any significant extra
effort.
Note: I am not sure what the correct answer would be from a
standard point of view. As far as I can tell, all iterator
types for standard containers are implementation defined.
Yep. All that is required is that they support both prefix and
postfix ++ (and -- if they are bidirectional) on an lvalue.