3766. view_interface::cbegin is underconstrained

Section: 25.5.3.1 [view.interface.general] Status: C++23 Submitter: Hewill Kang Opened: 2022-09-04 Last modified: 2023-11-22

Priority: 2

View all other issues in [view.interface.general].

View all issues with C++23 status.

Discussion:

Currently, view_interface::cbegin simply returns ranges::cbegin(derived()), which returns the type alias const_iterator for its iterator, which requires that the template parameter I must model the input_iterator.

Given that view_interface::cbegin does not have any constraints, when D models only output_range, calling its cbegin() will result in a hard error inside the function body:

#include <ranges>
#include <vector>

int main() {
  std::vector<int> v;
  auto r = std::views::counted(std::back_inserter(v), 3);
  auto b = r.cbegin(); // hard error
}

We should add a constraint for view_interface::cbegin that D must model input_range.

[2022-09-23; Reflector poll]

Set priority to 2 after reflector poll.

This should be done for cend too.

Previous resolution [SUPERSEDED]:

This wording is relative to N4917.

  1. Modify 25.5.3.1 [view.interface.general] as indicated:

    namespace std::ranges {
      template<class D>
        requires is_class_v<D> && same_as<D, remove_cv_t<D>>
      class view_interface {
        […]
      public:
        […]
        constexpr auto cbegin() requires input_range<D> {
          return ranges::cbegin(derived());
        }
        constexpr auto cbegin() const requires input_range<const D> {
          return ranges::cbegin(derived());
        }
        […]
      };
    }
    

[2022-09-25; Hewill provides improved wording]

[Kona 2022-11-08; Accepted at joint LWG/SG9 session. Move to Immediate]

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Immediate → WP.]

Proposed resolution:

This wording is relative to N4917.

  1. Modify 25.5.3.1 [view.interface.general] as indicated:

    namespace std::ranges {
      template<class D>
        requires is_class_v<D> && same_as<D, remove_cv_t<D>>
      class view_interface {
        […]
      public:
        […]
        constexpr auto cbegin() requires input_range<D> {
          return ranges::cbegin(derived());
        }
        constexpr auto cbegin() const requires input_range<const D> {
          return ranges::cbegin(derived());
        }
        constexpr auto cend() requires input_range<D> {
          return ranges::cend(derived());
        }
        constexpr auto cend() const requires input_range<const D> {
          return ranges::cend(derived());
        }
        […]
      };
    }