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.
4303.std::decay_t
in the specification of ranges::distance
is problematic
Section: 24.4.4.3 [range.iter.op.distance] Status: New Submitter: Jiang An Opened: 2025-07-24 Last modified: 2025-08-16
Priority: Not Prioritized
View all other issues in [range.iter.op.distance].
View all issues with New status.
Discussion:
This is discovered when implementing the resolution LWG 4242(i). Per LWG 4242(i), it is intended to allow ranges::distance
to handle volatile
-qualified iterator values. However, the uses of decay_t
(established per LWG 3664(i)) are still problematic, because when sized_sentinel_for<S, decay_t<I>>
is modeled, there's no semantic or syntactic requirement that S
shall work with volatile-qualified I
.
operator==
or operator-
intendedly rejects volatile-qualified iterators. And even when they accept volatile-qualified iterators, the additional semantic requirements imposed by sized_sentinel_for<S, decay_t<I>>
are still undesired. I think we should only decay arrays and keep volatile
for non-array arguments.
Proposed resolution:
This wording is relative to N5014.
Modify 24.2 [iterator.synopsis], header <iterator>
synopsis, as indicated:
[…] namespace std: { […] // 24.4.4.3 [range.iter.op.distance], ranges::distance template<class T> using distance-iterator-t = // exposition only conditional_t<is_array_v<remove_reference_t<T>>, decay_t<T>, remove_const_t<remove_reference_t<T>>>; template<class I, sentinel_for<I> S> requires (!sized_sentinel_for<S, I>) constexpr iter_difference_t<I> distance(I first, S last); // freestanding template<class I, sized_sentinel_for<decay_tdistance-iterator-t<I>> S> constexpr iter_difference_t<decay_tdistance-iterator-t<I>> distance(I&& first, S last); // freestanding template<range R> constexpr range_difference_t<R> distance(R&& r); // freestanding […] }
Modify 24.4.4.3 [range.iter.op.distance] as indicated:
template<class I, sized_sentinel_for<decay_tdistance-iterator-t<I>> S> constexpr iter_difference_t<decay_tdistance-iterator-t<I>> distance(I&& first, S last);-3- Effects: Equivalent to:
if constexpr (!is_array_v<remove_reference_t<I>>) return last - first; else return last - static_cast<decay_t<I>>(first);
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