This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3450. The `const` overloads of `take_while_view::begin/end` are underconstrained

Section: 24.7.9.2 [range.take.while.view] Status: WP Submitter: Tim Song Opened: 2020-06-06 Last modified: 2020-11-09

Priority: 0

View all other issues in [range.take.while.view].

View all issues with WP status.

Discussion:

The `const` overloads of `take_while_view::begin` and `take_while_view::end` are underconstrained: they should require the predicate to model `indirect_unary_predicate<iterator_t<const V>>`. A simple example is

>         #include <ranges>

>         auto v = std::views::single(1) | std::views::take_while([](int& x) { return true;});
>         static_assert(std::ranges::range<decltype(v)>);
>         static_assert(std::ranges::range<decltype(v) const>);
>         bool b = std::ranges::cbegin(v) == std::ranges::cend(v);

Here, the `static_assert`s pass but the comparison fails to compile. The other views using `indirect_unary_predicate` (`filter_view` and `drop_while_view`) do not have this problem because they do not support const-iteration.

[2020-07-17; Moved to Ready in telecon]

[2020-11-09 Approved In November virtual meeting. Status changed: Ready → WP.]

Proposed resolution:

This wording is relative to N4861.

1. Modify 24.7.9.2 [range.take.while.view], class template `take_while_view` synopsis, as indicated:

   > >     namespace std::ranges {
   > >         template<view V, class Pred>
   > >           requires input_range<V> && is_object_v<Pred> &&
   > >                    indirect_unary_predicate<const Pred, iterator_t<V>>
   > >         class take_while_view : public view_interface<take_while_view<V, Pred>> {
   > >         […]

   > >         constexpr auto begin() requires (!simple-view<V>)
   > >         { return ranges::begin(base_); }

   > >         constexpr auto begin() const requires range<const V> && indirect_unary_predicate<const Pred, iterator_t<const V>>
   > >         { return ranges::begin(base_); }

   > >         constexpr auto end() requires (!simple-view<V>)
   > >         { return sentinel<false>(ranges::end(base_), addressof(*pred_)); }

   > >         constexpr auto end() const requires range<const V> && indirect_unary_predicate<const Pred, iterator_t<const V>>
   > >         { return sentinel<true>(ranges::end(base_), addressof(*pred_)); }
   > >         };
   > >     }