reverse iterator operator==

A

Alexander Stippler

Hello,

the standard requires a type reverse_iterator. But in the form it is
required and implemented for all compilers I know, there is IMO something
missing, which is essential for its usage.
With normal iterators you can compare a const_iterator and an iterator for
equality, using reverse_iterator as is, you can't. I can understand the
reason, why it's not provided. But does reverse_iterator make sense this
way? A simple example:

std::vector<int> v;
std::vector<int>::const_reverse_iterator it;
for (it=v.rbegin(); it!=v.rend(); ++it) {}

This won't compile, since it and v.rend() have different types and no
operator!= is defined for those. Isn't it unnatural that I can do the same
loop as above traversing the vector forward and it is legal code, but by
inverting the traversal direction, I create illegal code?
Any experiences with reverse_iterators? What do you think?

regards,
alex
 
R

Ron Natalie

Alexander Stippler said:
With normal iterators you can compare a const_iterator and an iterator for
equality

Nothing says you can compare iterator and const_iterator either. It's just
coincidence on your implementation that the types are convertible.

You need to use the constness of the iterator appropriate for the constness
of the object you call the r.begin()/r.end() on .

If you really want to force it to const iterators:

for(it = const_cast<const std::vector<int>&>(v).rbegin(); it != const_cast<const std::vector<int>&>(v).rend(); ++i) ..,
 
J

John Ericson

Ron Natalie said:
"Alexander Stippler" <[email protected]> wrote in
message news:[email protected]...
Nothing says you can compare iterator and const_iterator either. It's just
coincidence on your implementation that the types are convertible.

You need to use the constness of the iterator appropriate for the constness
of the object you call the r.begin()/r.end() on .

If you really want to force it to const iterators:

for(it = const_cast<const std::vector<int>&>(v).rbegin();

Say what? Isn't there an implicit conversion from iterator
to const_iterator, and from reverse_iterator to
const_reverse_iterator?
- -
Best regards, John E.
 
A

Alexander Stippler

Ron said:
You need to use the constness of the iterator appropriate for the
constness of the object you call the r.begin()/r.end() on .

Using const_iterators you can (to some extent) be sure, the container
used isn't modified during the iteration. That's a feature, I use heavily
because it can prevent some errors. I think you are correct, since the
standard doesn't enforce the comparison possibility. I do not really like
it, but I think I will stop using const_iterators that heavily restricting
me to use them only when neccessary (through constness of the underlying
container).
 
N

Nick Hounsome

Ron Natalie said:
Nothing says you can compare iterator and const_iterator either. It's just
coincidence on your implementation that the types are convertible.

No it isn't - the standard section on iterators says nothing about being
convertible but the section on containers puts a requirement on standard
containers that their iterators are convertible to const_iterator except for
output iterators.
 
R

Ron Natalie

Nick Hounsome said:
No it isn't - the standard section on iterators says nothing about being
convertible but the section on containers puts a requirement on standard
containers that their iterators are convertible to const_iterator except for
output iterators.

OK, iterator should be convertible to const_iterator. You're misreading the
exception though. That "except for output iterator" isn't talking about the
conversion. It's saying that X::iterator can't be an output_iterator. No conversion
is required for reverse_iterators.
 
J

John Ericson

Ron Natalie said:
OK, iterator should be convertible to const_iterator. You're misreading the
exception though. That "except for output iterator" isn't talking about the
conversion. It's saying that X::iterator can't be an
output_iterator. No conversion
is required for reverse_iterators.

The Library Working Group issues #179 and #280 address
mixing comparisons of (const_iterator, iterator) and
(reverse_iterator, const_reverse_iterator), respectively.
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179

The OP doesn't have to mix iterator types, though, and could
just make a const reference to the container, and get
const_reverse_iterators from the const reference to the
container.

Best regards, John E.
 
N

Nick Hounsome

John Ericson said:
output_iterator. No conversion

The Library Working Group issues #179 and #280 address
mixing comparisons of (const_iterator, iterator) and
(reverse_iterator, const_reverse_iterator), respectively.
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179

scuse my ignorance but isn't the problem described in the link solely down
to the apparently poor idea of making operator== a member?

If it is free function:

template <class C>
bool operator==(typename C::const_iterator& a, typename C::const_iterator&
b);

Then the conversion from iterator to const_iterator would sort it.

Actually I think that in practice it has to be a whole familly of
functions:
template <typename T> bool operator==(typename set<T>::const_iterator& a,
typename set<T>::const_iterator& b);
+ for map list etc.
And obviously only for those where an iterator is a class and not just a
typedef for T*
 
J

John Ericson

<snip>

JE> > The Library Working Group issues #179 and #280 address
JE> > mixing comparisons of (const_iterator, iterator) and
JE> > (reverse_iterator, const_reverse_iterator),
respectively.
JE> >
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179Nick> scuse my ignorance but isn't the problem described in
the link solely down
Nick> to the apparently poor idea of making operator== a
member?<snip>

Not your ignorance - the link issues are whether the
Standard should require that comparisons of
(reverse_)iterators and const_(reverse_)iterators be
supported, not necessarily the mechanism of implementation.
If the comparison operator were template functions with a
single type parameter and the types are different, then it
would be understandable if the type weren't deducible from
those different types. For member functions, I had expected
that, for example, (const_iterator == iterator) would be OK
(iterator being promoted to const_iterator), while (iterator
== const_iterator) could be trouble. For the
reverse_iterator case, perhaps the OP's implementation is
using a template operator, and is not able to deduce the
template parameter. If the Standard doesn't require that
comparisons of reverse_iterators and const_reverse_iterators
be supported, then I suppose one should make the iterators
in the comparison match. I haven't been doing that with
iterator and const_iterator. Maybe ignorance on my part?

Best regards, John E.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,616
Members
45,306
Latest member
TeddyWeath

Latest Threads

Top