Created on 2022-08-01.00:00:00 last changed 27 months ago
Proposed resolution:
This wording is relative to N4910.
Modify [common.iter.cmp] as indicated:
template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2> requires sized_sentinel_for<S, I2> friend constexpr iter_difference_t<I2> operator-( const common_iterator& x, const common_iterator<I2, S2>& y);-5- Preconditions: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false.
-6- Returns: 0 if i and j are each 1, and otherwise static_cast<iter_difference_t<I2>>(get<i>(x.v_) - get<j>(y.v_)), where i is x.v_.index() and j is y.v_.index().
Modify [counted.iter.nav] as indicated:
template<common_with<I> I2> friend constexpr iter_difference_t<I2> operator-( const counted_iterator& x, const counted_iterator<I2>& y);-13- Preconditions: x and y refer to elements of the same sequence ([counted.iterator]).
-14- Effects: Equivalent to: return static_cast<iter_difference_t<I2>>(y.length - x.length);
[ 2022-08-23; Reflector poll ]
Set priority to 3 after reflector poll.
"I think common_iterator
should reject iterators with
integer-class difference types since it can't possibly achieve the design intent
of adapting them to Cpp17Iterators, so this issue should only affect
counted_iterator
."
"If the difference types of I
and I2
are different
then the operator-
can't be used to model
sized_sentinel_for
,
since i - i2
and i2 - i
would have different types.
Providing operator-
under such circumstances seems
to be of dubious value."
Both common_iterator and counted_iterator explicitly specify that the return type of their operator- is iter_difference_t<I2>, however, given that the calculated type may be iter_difference_t<I>, we should do an explicit conversion here since the latter is not necessarily implicitly convertible to the former:
#include <ranges>
struct Y;
struct X {
X(Y);
using difference_type =
#ifdef __GNUC__
std::ranges::__detail::__max_diff_type;
#elif defined(_MSC_VER)
std::_Signed128;
#endif
int& operator*() const;
X& operator++();
void operator++(int);
};
struct Y {
using difference_type = std::ptrdiff_t;
int& operator*() const;
Y& operator++();
void operator++(int);
};
int main() {
std::counted_iterator<Y> y;
return std::counted_iterator<X>(y) - y; // hard error in stdlibc++ and MSVC-STL
}
Daniel:
This issue shouldn't we voted until a decision for LWG 3749 has been made, because the first part of it overlaps with LWG 3749's second part.
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-08-23 15:25:16 | admin | set | messages: + msg12704 |
2022-08-07 09:35:46 | admin | set | messages: + msg12668 |
2022-08-01 00:00:00 | admin | create |