Consider the following code snippet:
#include <ranges>
auto r = std::views::iota(0) | std::views::take(0);
static_assert(std::ranges::sized_range<decltype(r)>);
gcc-trunk rejects it for required-expression std::ranges::size(r) is invalid. Why does r not model ranges::sized_range, i,e, why can't I use std::ranges::size on it?
Update
Compiles after using range-v3. Is this feature required for C++23, or is it an LWG issue?
#include <range/v3/all.hpp>
#include <ranges>
auto r = ranges::views::iota(0) | ranges::views::take(0);
static_assert(std::ranges::sized_range<decltype(r)>);
The problem seems to be that the sentinel_t of r in range-v3 is just ranges::default_sentinel which satisfies the std::sized_sentinel_for<ranges::counted_iterator>, since there is a valid operator- in [predef.iterators#iterators.counted] for those two types:
friend constexpr iter_difference_t<I> operator-( const counted_iterator& x, default_sentinel_t); friend constexpr iter_difference_t<I> operator-( default_sentinel_t, const counted_iterator& y);
But in namepace std::ranges, the sentinel_t of r is std::ranges::take_view<std::ranges::iota_view>::_Sentinel<true> which cannot convert to std::default_sentinel_t.