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.
3748.common_iterator
and counted_iterator
' operator-
are missing cast to return type
Section: 24.5.5.6 [common.iter.cmp], 24.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(i) has been made, because the first part of it overlaps with LWG 3749(i)'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 24.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:
-6- Returns:x.v_.valueless_by_exception()
andy.v_.valueless_by_exception()
are eachfalse
.0
ifi
andj
are each1
, and otherwisestatic_cast<iter_difference_t<I2>>(
get<i>(x.v_) - get<j>(y.v_)
)
, wherei
isx.v_.index()
andj
isy.v_.index()
.
Modify 24.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:
-14- Effects: Equivalent to:x
andy
refer to elements of the same sequence (24.5.7.1 [counted.iterator]).return static_cast<iter_difference_t<I2>>(y.length - x.length );
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4