3712. chunk_view and slide_view should not be default_initializable

Section: 25.7.29.2 [range.chunk.view.input], 25.7.29.6 [range.chunk.view.fwd], 25.7.30.2 [range.slide.view] Status: C++23 Submitter: Hewill Kang Opened: 2022-06-10 Last modified: 2023-11-22

Priority: Not Prioritized

View all other issues in [range.chunk.view.input].

View all issues with C++23 status.

Discussion:

Both chunk_view and slide_view have a precondition that N must be positive, but they are still default_initializable when the underlying range is default_initializable, which makes the member variable n_ initialized with an invalid value 0 when they are default-constructed, which produces the following unexpected result:

#include <ranges>

using V = std::ranges::iota_view<int, int>;
static_assert(std::ranges::slide_view<V>().empty()); // fails
static_assert(std::ranges::chunk_view<V>().empty()); // division by zero is not a constant expression

Although we could provide a default positive value for n_, I think a more appropriate solution would be to not provide the default constructor, since default-constructed values for integer types will never be valid.

[2022-06-21; Reflector poll]

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

[2022-07-15; LWG telecon: move to Ready]

[2022-07-25 Approved at July 2022 virtual plenary. Status changed: Ready → WP.]

Proposed resolution:

This wording is relative to N4910.

  1. Modify 25.7.29.2 [range.chunk.view.input] as indicated:

    namespace std::ranges {
      […]
     
      template<view V>
        requires input_range<V>
      class chunk_view : public view_interface<chunk_view<V>> {
        V base_ = V();                                        // exposition only
        range_difference_t<V> n_ = 0;                         // exposition only
        range_difference_t<V> remainder_ = 0;                 // exposition only
        […]
      public:
        chunk_view() requires default_initializable<V> = default;
        constexpr explicit chunk_view(V base, range_difference_t<V> n);
        […]
      };
      […]
    }
    
  2. Modify 25.7.29.6 [range.chunk.view.fwd] as indicated:

    namespace std::ranges {
      template<view V>
        requires forward_range<V>
      class chunk_view<V> : public view_interface<chunk_view<V>> {
        V base_ = V();                   // exposition only
        range_difference_t<V> n_ = 0;    // exposition only
        […]
      public:
        chunk_view() requires default_initializable<V> = default;
        constexpr explicit chunk_view(V base, range_difference_t<V> n);
    
        […]
      };
    }
    
  3. Modify 25.7.30.2 [range.slide.view] as indicated:

    namespace std::ranges {
      […]
    
      template<forward_range V>
        requires view<V>
      class slide_view : public view_interface<slide_view<V>> {
        V base_ = V();                      // exposition only
        range_difference_t<V> n_ = 0;       // exposition only
        […]
      public:
        slide_view() requires default_initializable<V> = default;
        constexpr explicit slide_view(V base, range_difference_t<V> n);
    
        […]
      };
      […]
    }