The following works:
#include <vector>
#include <ranges>
int main() {
auto view = std::vector<int>{0,1,2,3,4};
auto s = std::span{view.begin(), view.end()};
std::vector test(view.begin(), view.end());
}
But this does not:
#include <vector>
#include <ranges>
int main() {
auto view = std::ranges::iota_view{0, 1000};
auto s = std::span{view.begin(), view.end()};
std::vector test(view.begin(), view.end());
}
The problem is, I have some generic code where I want to send it a range and then create a span over the range. I've tried sending in a vector
and it is fine. The result from iota
fails.
template <typename TRange>
requires std::ranges::random_access_range<TRange>
void Foo(TRange const & r)
{
// The algorithm starts with a full span and then partitions
auto s = std::span(r.begin(), r.end());
}
The code is being ported from boost, and there I would have used boost::make_iterator_range()
, but my guess that this is superseded in the standard library by std::span
. Is this right?
You don't.
std::span<int>
requires a contiguous range.std::vector<int>
is a contiguous range, butviews::iota(0, 100)
is not contiguous, it's just random access.Side-note: write
views::iota(0, 1000)
, don't writeranges::iota_view{0, 1000}
. There is almost never any reason to writeranges::meow_view
overviews::meow
, and it can easily be worse - the latter doesn't always give you something whose type is the former. Think ofmeow_view
as an implementation detail.