Title
lazy_split_view::outer-iterator::value_type should not provide default constructor
Status
new
Section
[range.lazy.split.outer.value]
Submitter
Hewill Kang

Created on 2023-11-11.00:00:00 last changed 1 week ago

Messages

Date: 2023-11-18.13:05:11

Proposed resolution:

This wording is relative to N4964.

  1. Modify [range.lazy.split.outer.value], class split_view::outer-iterator::value_type synopsis, as indicated:

    namespace std::ranges {
      template<input_range V, forward_range Pattern>
        requires view<V> && view<Pattern> &&
                 indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&
                 (forward_range<V> || tiny-range<Pattern>)
      template<bool Const>
      struct lazy_split_view<V, Pattern>::outer-iterator<Const>::value_type
        : view_interface<value_type> {
      private:
        outer-iterator i_ = outer-iterator();               // exposition only
      
        constexpr explicit value_type(outer-iterator i);    // exposition only
    
      public:
        value_type() = default;
        constexpr explicit value_type(outer-iterator i);
    
        constexpr inner-iterator<Const> begin() const;
        constexpr default_sentinel_t end() const noexcept;
      };
    }
    
Date: 2023-11-11.00:00:00

After P2325, there is no reason for lazy_split_view::outer-iterator::value_type to provide a default constructor, which only leads to unexpected behavior:

#include <ranges>

constexpr int arr[] = {42};
constexpr auto split = arr | std::views::lazy_split(0);
static_assert(!std::ranges::range_value_t<decltype(split)>{});  // UB, dereferencing a null pointer

Also, the other constructor should be private because it makes no sense for the user to construct it arbitrarily, which is not the intention.

History
Date User Action Args
2023-11-18 13:05:11adminsetmessages: + msg13867
2023-11-11 00:00:00admincreate