This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
Section: 25.5.5.6 [common.iter.cmp], 25.5.7.5 [counted.iter.nav] Status: New Submitter: Hewill Kang Opened: 2022-08-01 Last modified: 2022-08-23
Priority: 3
View all issues with New status.
Discussion:
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.
[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."
Proposed resolution:
This wording is relative to N4910.
Modify 25.5.5.6 [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 25.5.7.5 [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 (25.5.7.1 [counted.iterator]).
-14- Effects: Equivalent to: return static_cast<iter_difference_t<I2>>(y.length - x.length);