我正在处理 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;
然后我会进行排序,就像 range-v3 对
|action::sort
所做的那样,但我知道这个实现是不一样的。
我发现的排序方式是:
ints = std::vector(std::ranges::begin(rr), std::ranges::end(rr));
std::ranges::sort(ints);
我错了吗?有人知道如何用管道样式对视图进行排序吗?
然后我会进行排序,就像 range-v3 对
... 所做的那样|action::sort
不,你实际上不能像这样排序
rr
:
rr |= ranges::actions::sort; // error
因为
rr
是一个view
。虽然 view
可以提供对底层范围的可变访问,但 sort
还需要范围来支持随机访问。像 view
这样延迟生成的 rr
不允许这样做。
您可以像您所做的那样从
vector
创建 rr
,然后您可以在该范围内使用 actions
:
ints |= ranges::actions::sort; // ok
然而,c++20 没有任何 actions
(希望我们能在 c++23 中得到它们),所以在那之前你必须在不使用管道语法的情况下调用算法
sort
:
std::ranges::sort(ints); // ok
ranges::to<multiset>()
为此:
#include <iostream>
#include <ranges>
#include <vector>
#include <set>
using namespace std;
std::vector ints{ 6, 5, 2, 8 };
auto even = [](int i) {
return 0 == i % 2;
};
// ranges...
int main(){
string buffer = ints | views::filter(even)
| views::transform([](auto i) {return i * i;})
| ranges::to<multiset>()
| views::transform([](int i){return to_string(i);})
| views::join_with(',')
| ranges::to<string>();
printf("%s", buffer.c_str());
}