This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

### 179. Comparison of const_iterators to iterators doesn't work

Section: 22.2 [container.requirements] Status: CD1 Submitter: Judy Ward Opened: 1998-07-02 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [container.requirements].

View all issues with CD1 status.

Discussion:

Currently the following will not compile on two well-known standard library implementations:

>     #include <set>
>     using namespace std;

>     void f(const set<int> &s)
>     {
>       set<int>::iterator i;
>       if (i==s.end()); // s.end() returns a const_iterator
>     }

The reason this doesn't compile is because operator== was implemented as a member function of the nested classes set:iterator and set::const_iterator, and there is no conversion from const_iterator to iterator. Surprisingly, (s.end() == i) does work, though, because of the conversion from iterator to const_iterator.

I don't see a requirement anywhere in the standard that this must work. Should there be one? If so, I think the requirement would need to be added to the tables in section 24.1.1. I'm not sure about the wording. If this requirement existed in the standard, I would think that implementors would have to make the comparison operators non-member functions.

This issues was also raised on comp.std.c++ by Darin Adler. The example given was:

>     bool check_equal(std::deque<int>::iterator i,
>     std::deque<int>::const_iterator ci)
>     {
>     return i == ci;
>     }

Comment from John Potter:

> In case nobody has noticed, accepting it will break reverse_iterator.

> The fix is to make the comparison operators templated on two types.

>         template <class Iterator1, class Iterator2>
>         bool operator== (reverse_iterator<Iterator1> const& x,
>                          reverse_iterator<Iterator2> const& y);

> Obviously: return x.base() == y.base();

> Currently, no reverse_iterator to const_reverse_iterator compares are valid.

> BTW, I think the issue is in support of bad code. Compares should be between two iterators of the same type. All std::algorithms require the begin and end iterators to be of the same type.

Proposed resolution:

Insert this paragraph after 22.2 [container.requirements] paragraph 7:

> In the expressions

>         i == j
>         i != j
>         i < j
>         i <= j
>         i >= j
>         i > j
>         i - j

> Where i and j denote objects of a container's iterator type, either or both may be replaced by an object of the container's const_iterator type referring to the same element with no change in semantics.

[post-Toronto: Judy supplied a proposed resolution saying that `iterator` and `const_iterator` could be freely mixed in iterator comparison and difference operations.]

[Redmond: Dave and Howard supplied a new proposed resolution which explicitly listed expressions; there was concern that the previous proposed resolution was too informal.]

Rationale:

The LWG believes it is clear that the above wording applies only to the nested types `X::iterator` and `X::const_iterator`, where `X` is a container. There is no requirement that `X::reverse_iterator` and `X::const_reverse_iterator` can be mixed. If mixing them is considered important, that's a separate issue. (Issue 280.)