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?
CodePudding user response:
You don't.
std::span<int>
requires a contiguous range. std::vector<int>
is a contiguous range, but views::iota(0, 100)
is not contiguous, it's just random access.
Side-note: write views::iota(0, 1000)
, don't write ranges::iota_view{0, 1000}
. There is almost never any reason to write ranges::meow_view
over views::meow
, and it can easily be worse - the latter doesn't always give you something whose type is the former. Think of meow_view
as an implementation detail.
CodePudding user response:
The thing I'm looking for is not std::span
but std::ranges::subrange
, which is more generic, and works with non-contiguous memory.
#include <vector>
#include <ranges>
int main() {
auto view = std::views::iota(0, 1000);
auto s = std::ranges::subrange{view.begin(),view.end()};
std::vector test(view.begin(), view.end());
}