如何从 std::iota 构造跨度?

bra*_*ing 1 c++ c++20 std-span

以下作品:

#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());
}
Run Code Online (Sandbox Code Playgroud)

但这并不:

#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());
}
Run Code Online (Sandbox Code Playgroud)

问题是,我有一些通用代码,我想向它发送一个范围,然后在该范围上创建一个跨度。我试过发送一个vector,没问题。结果iota失败。

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());
}
Run Code Online (Sandbox Code Playgroud)

该代码是从 boost 移植的,在那里我会使用boost::make_iterator_range(),但我猜测这在标准库中已被std::span. 这是正确的吗?

Bar*_*rry 6

你不知道。

std::span<int>需要一个连续的范围。std::vector<int>是一个连续的范围,但views::iota(0, 100)不是连续的,它只是随机访问。


旁注:写views::iota(0, 1000),不写ranges::iota_view{0, 1000}。几乎没有任何理由要重写ranges::meow_viewviews::meow而且很容易变得更糟 - 后者并不总是给你属于前者类型的东西。将其视为meow_view实施细节。

  • @bradgonesurfing“如果有帮助的话”……好吧,如果你问了你实际遇到的问题,那将会有所帮助。如果问题是“如何获得任意随机访问视图的前半部分或后半部分?” 那么答案仍然不是 `ranges::subrange`,它可能是 `views::take` 或 `views::drop`。 (2认同)