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.

4242. ranges::distance does not work with volatile iterators

Section: 24.4.4.3 [range.iter.op.distance] Status: New Submitter: Hewill Kang Opened: 2025-04-12 Last modified: 2025-04-13

Priority: Not Prioritized

View all other issues in [range.iter.op.distance].

View all issues with New status.

Discussion:

After LWG 3664(i), ranges::distance computes the distance between last and first by returning last - static_cast<const decay_t<I>&>(first) when the two are subtractable. However, this will cause a hard error if first is volatile-qualified (demo):

#include <iterator>

int main() {
  int arr[] = {1, 2, 3};
  int* volatile ptr = arr;
  // return std::distance(ptr, arr + 3);      // this is ok
  return std::ranges::distance(ptr, arr + 3); // hard error
}

The resolution changes the Effects of LWG 3664(i) from "cute" to "noncute".

Proposed resolution:

This wording is relative to N5008.

  1. Modify 24.4.4.3 [range.iter.op.distance] as indicated:

    template<class I, sized_sentinel_for<decay_t<I>> S>
      constexpr iter_difference_t<decay_t<I>> ranges::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<const decay_t<I>&>(first);