3589. The const lvalue reference overload of get for subrange does not constrain I to be copyable when N == 0

Section: 25.5.4 [range.subrange] Status: C++23 Submitter: Hewill Kang Opened: 2021-09-08 Last modified: 2023-11-22

Priority: 3

View all other issues in [range.subrange].

View all issues with C++23 status.

Discussion:

The const lvalue reference overload of get used for subrange only constraint that N < 2, this will cause the "discards qualifiers" error inside the function body when applying get to the lvalue subrange that stores a non-copyable iterator since its begin() is non-const qualified, we probably need to add a constraint for it.

[2021-09-20; Reflector poll]

Set priority to 3 after reflector poll.

[2021-09-20; Reflector poll]

Set status to Tentatively Ready after six votes in favour during reflector poll.

[2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4892.

  1. Modify 25.5.4 [range.subrange] as indicated:

    namespace std::ranges {
      […]
      template<size_t N, class I, class S, subrange_kind K>
        requires ((N < 2== 0 && copyable<I>) || N == 1)
        constexpr auto get(const subrange<I, S, K>& r);
    
      template<size_t N, class I, class S, subrange_kind K>
        requires (N < 2)
        constexpr auto get(subrange<I, S, K>&& r);
    }
    
  2. Modify 25.5.4.3 [range.subrange.access] as indicated:

      […]
      template<size_t N, class I, class S, subrange_kind K>
        requires ((N < 2== 0 && copyable<I>) || N == 1)
        constexpr auto get(const subrange<I, S, K>& r);
      template<size_t N, class I, class S, subrange_kind K>
        requires (N < 2)
        constexpr auto get(subrange<I, S, K>&& r);
    

    -10- Effects: Equivalent to:

    if constexpr (N == 0)
      return r.begin();
    else
      return r.end();