考虑以下代码片段:
#include <ranges>
auto r = std::views::iota(0) | std::views::take(0);
static_assert(std::ranges::sized_range<decltype(r)>);
gcc-trunk拒绝它,因为required-expression std::ranges::size(r)
无效。为什么r
没有 model ranges::sized_range
,即为什么我不能使用std::ranges::size
它?
更新
使用range-v3后编译。C++23 是否需要此功能,还是 LWG 问题?
#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)>);
问题似乎是sentinel_t
inr
恰好range-v3
满足ranges::default_sentinel
,因为这两种类型在[predef.iterators#iterators.counted]std::sized_sentinel_for<ranges::counted_iterator>
中有一个有效的:operator-
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);
但是在 中namepace std::ranges
,sentinel_t
ofr
是std::ranges::take_view<std::ranges::iota_view>::_Sentinel<true>
不能转换成的std::default_sentinel_t
。