#include <iostream>
#include <cstdlib>
#include <vector>
#include <ranges>
#include <algorithm>
using namespace std;
int main()
{
vector<int> ints = {1,2,3,4,5};
auto v = ints | views::take_while([](int i){return i<3;}) ;
for (int i : v) std::cout << i << ' ';
std::cout << '\n';
int size = v.size();
std::cout << size << std::endl;
}
v.size() does not compile. How do you do this ?
prog.cc: In function 'int main()':
prog.cc:16:23: error: no matching function for call to 'std::ranges::take_while_view<std::ranges::ref_view<std::vector<int> >, main()::<lambda(int)> >::size()'
16 | int size = v.size();
| ^
In file included from prog.cc:5:
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/ranges:144:7: note: candidate: 'constexpr auto std::ranges::view_interface<_Derived>::size() requires (forward_range<_Derived>) && (sized_sentinel_for<decltype(std::ranges::__cust::end((declval<_Tp&>)())), decltype(std::__detail::__ranges_begin((declval<_Container&>)()))>) [with _Derived = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int> >, main()::<lambda(int)> >]'
144 | size()
| ^~~~
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/ranges:144:7: note: constraints not satisfied
In file included from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/stl_iterator_base_types.h:71,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/stl_algobase.h:65,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/char_traits.h:39,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/ios:40,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/ostream:38,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/iostream:39,
from prog.cc:2:
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h: In instantiation of 'constexpr auto std::ranges::view_interface<_Derived>::size() requires (forward_range<_Derived>) && (sized_sentinel_for<decltype(std::ranges::__cust::end((declval<_Tp&>)())), decltype(std::__detail::__ranges_begin((declval<_Container&>)()))>) [with _Derived = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int> >, main()::<lambda(int)> >]':
prog.cc:16:23: required from here
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:555:13: required for the satisfaction of 'sized_sentinel_for<std::ranges::sentinel_t<_Tp>, decltype (std::__detail::__ranges_begin(declval<_Container&>()))>' [with _Tp = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int, std::allocator<int> > >, main::._anon_124>; _Container = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int, std::allocator<int> > >, main::._anon_124>]
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:557:8: in requirements with 'const _Iter& __i', 'const _Sent& __s' [with _Arg = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >; _Sent = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int, std::allocator<int> > >, main::._anon_124>::_Sentinel<true>; _Iter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:559:13: note: the required expression '(__s - __i)' is invalid
559 | { __s - __i } -> same_as<iter_difference_t<_Iter>>;
| ~~~~^~~~~
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:560:13: note: the required expression '(__i - __s)' is invalid
560 | { __i - __s } -> same_as<iter_difference_t<_Iter>>;
| ~~~~^~~~~
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
In file included from prog.cc:5:
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/ranges:150:7: note: candidate: 'constexpr auto std::ranges::view_interface<_Derived>::size() const requires (forward_range<const _Derived>) && (sized_sentinel_for<decltype(std::ranges::__cust::end((declval<const _Range&>)())), decltype(std::__detail::__ranges_begin((declval<const _Range&>)()))>) [with _Derived = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int> >, main()::<lambda(int)> >]'
150 | size() const
| ^~~~
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/ranges:150:7: note: constraints not satisfied
In file included from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/stl_iterator_base_types.h:71,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/stl_algobase.h:65,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/char_traits.h:39,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/ios:40,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/ostream:38,
from /opt/wandbox/gcc-10.2.0/include/c /10.2.0/iostream:39,
from prog.cc:2:
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h: In instantiation of 'constexpr auto std::ranges::view_interface<_Derived>::size() const requires (forward_range<const _Derived>) && (sized_sentinel_for<decltype(std::ranges::__cust::end((declval<const _Range&>)())), decltype(std::__detail::__ranges_begin((declval<const _Range&>)()))>) [with _Derived = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int> >, main()::<lambda(int)> >]':
prog.cc:16:23: required from here
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:555:13: required for the satisfaction of 'sized_sentinel_for<std::ranges::sentinel_t<const _Range>, decltype (std::__detail::__ranges_begin(declval<const _Range&>()))>' [with _Range = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int, std::allocator<int> > >, main::._anon_124>]
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:557:8: in requirements with 'const _Iter& __i', 'const _Sent& __s' [with _Arg = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >; _Sent = std::ranges::take_while_view<std::ranges::ref_view<std::vector<int, std::allocator<int> > >, main::._anon_124>::_Sentinel<true>; _Iter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:559:13: note: the required expression '(__s - __i)' is invalid
559 | { __s - __i } -> same_as<iter_difference_t<_Iter>>;
| ~~~~^~~~~
/opt/wandbox/gcc-10.2.0/include/c /10.2.0/bits/iterator_concepts.h:560:13: note: the required expression '(__i - __s)' is invalid
560 | { __i - __s } -> same_as<iter_difference_t<_Iter>>;
| ~~~~^~~~~
CodePudding user response:
Since take_while
and its ilk shorten the size of the list in unpredictable ways, those range adaptors cannot return a sized_range
, even if the input itself is sized. sized_range
requires that the range can compute the size in O(1) time, and take_while
's view cannot do that.
So if you want the size (and you shouldn't), you will have to compute it yourself. You could also use std::ranges::distance
on the range.