Created on 1998-07-02.00:00:00 last changed 171 months ago
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.)
[ Redmond: Dave and Howard supplied a new proposed resolution which explicitly listed expressions; there was concern that the previous proposed resolution was too informal. ]
[ post-Toronto: Judy supplied a proposed resolution saying that iterator and const_iterator could be freely mixed in iterator comparison and difference operations. ]
Proposed resolution:
Insert this paragraph after [container.requirements] paragraph 7:
In the expressions
i == j i != j i < j i <= j i >= j i > j i - jWhere 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.
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.
History | |||
---|---|---|---|
Date | User | Action | Args |
2010-10-21 18:28:33 | admin | set | messages: + msg1765 |
2010-10-21 18:28:33 | admin | set | messages: + msg1764 |
2010-10-21 18:28:33 | admin | set | messages: + msg1763 |
2010-10-21 18:28:33 | admin | set | messages: + msg1762 |
1998-07-02 00:00:00 | admin | create |