C++20 范围和排序

Chr*_*ris 5 c++ sorting c++20 std-ranges

我正在处理 C++ 20 的最后 4 个,试图学习新的主要特性。从网上尝试一些与范围相关的代码,我写了:

std::vector ints{ 6, 5, 2, 8 };
auto even = [](int i) {
    return 0 == i % 2;
};

// ranges...
auto rr = ints | std::views::filter(even) 
               | std::views::transform([](auto i) {
                   return i * i;
                 })
               | std::views::reverse;
Run Code Online (Sandbox Code Playgroud)

然后我会排序,就像 range-v3 对 所做的那样|action::sort,但我知道这个实现是不一样的。

The way I've found to sort is:

ints = std::vector(std::ranges::begin(rr), std::ranges::end(rr));
std::ranges::sort(ints);
Run Code Online (Sandbox Code Playgroud)

Am I wrong? Does anybody know how to sort with pipe style the view ?

cig*_*ien 6

然后我会排序,就像 range-v3 对|action::sort...

不,你实际上不能这样排序rr

rr |= ranges::actions::sort; // error
Run Code Online (Sandbox Code Playgroud)

因为rr是一个view. 虽然views 可以提供对底层范围的可变访问,但sort还需要范围支持随机访问。懒惰生成的view喜欢rr不允许这样做。

您可以像以前一样创建一个vectorfrom rr,然后您可以actions在该范围内使用:

ints |= ranges::actions::sort;  // ok
Run Code Online (Sandbox Code Playgroud)

然而,c++20 没有actions(希望我们能在 c++23 中得到它们),所以在那之前你必须调用sort没有管道语法的算法:

std::ranges::sort(ints);  // ok
Run Code Online (Sandbox Code Playgroud)

  • 反转随机访问迭代器仍然会给你一个随机访问迭代器,这部分很好。`transform` 给你一个纯右值,这使得事情不可排序,但如果它给出一个左值,那就没问题了。例如 `sort(iota(0u, v.size()) | transform([&v](int i) -> int& { return v[i]; }));` 是一种有效的方法,尽管很荒谬排序(v);` (2认同)