take view of unbounded iota is not a sized range

Viewed 55

Consider the following code

#include <ranges>
#include <iostream>
int main() {
  auto int_view = std::views::iota(0, 20) | std::views::take(15);
  std::cout << int_view.size() << std::endl;
  return 0;
}

This compiles fine and prints 15 as the size of int_view. However if we make the iota unbounded like iota(0) instead of iota(0,20), then that code won't compile because std::ranges::take_view<_Vp>::size() requires a sized_range, which the unbounded iota is clearly not. My question is why does it require a sized range? once we take a number of elements the corresponding view should be able to know it's size in constant time.

1 Answers

views::take only guarantees an upper bound on the size of the range, not its exact size which is what .size() must return.

C++ ranges/views are either bounded (have .size() and satisfy std::ranges::sized_range) or unbounded, there is no finer distinction for infinite ranges or minimum-/maximum-guaranteed lengths.

iota(0) returns an unbounded range, views::take therefore has no idea how many elements there are, could be zero or could be infinite for all it knows, and so the take must be of unknown size - unbounded.

Related