Home > Enterprise >  How to construct a span from std::iota?
How to construct a span from std::iota?

Time:01-25

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());
}
  • Related