c++ - 如何在 C++20 范围内将投影与变换结合起来
问题描述
C++20ranges::sort
支持投影,这很好,但我想做更复杂的事情,特别是对投影成员上的函数结果进行排序。
对于函数调用,我尝试了转换然后对该视图进行排序,但 C++20 排序似乎不适用于视图,这个答案解释了原因(对于 range-v3)。
换句话说,我可以在不使用 lambda/functor 的情况下编写它吗?
struct S{
int val;
};
int origin = 47;
// assume we can not change Distance to take S
int Distance(int val){
return std::abs(val - origin);
}
void my_sort(std::vector<S> ss) {
std::ranges::sort(ss, std::greater<>{}, [](const S& s){
return Distance(s.val);
});
}
解决方案
好像你想要函数组合:
void my_sort(std::vector<S>& ss) {
std::ranges::sort(ss, std::greater<>{}, compose(Distance, &S::val));
}
哪里compose(f, g)(x)
有f(g(x))
。Boost.Hof 有一个compose
,在 range-v3 的某个地方也有一个。但是标准库中没有。
对于函数调用,我尝试了转换,然后对该视图进行排序,
sort(r, less(), f)
和之间有很大的区别sort(r | transform(f), less())
:前者r
使用函数f
作为排序键进行排序,后者专门对转换后的值进行排序。一个展示差异的具体例子:
struct X {
int i;
int j;
};
vector<X> xs = {X{1, 2}, X{2, 1}, X{0, 7}};
// this would give you (0, 7), (1, 2), (2, 1)
// because we're sorting by the i
ranges::sort(xs, less(), &X::i);
// this would have given you (0, 2), (1, 1), (2, 7)
// because we're sorting the i's independently
ranges::sort(xs | views::transform(&X::i), less());
推荐阅读
- visual-studio - 如何使用位于 Visual Studio C++ 项目(Windows)中其他文件夹中的 dll?
- java - Windows 主机上 Centos 7 Docker 容器中的 Java Swing GUI
- javascript - Grunt 未能建立在一些有效的 js 语法上
- python - pandas dtype period [Q-DEC] 更改为 object
- reactjs - 如何修复 - src/pages/Leaflet/osm-providers.js 第 1:1 行:在导出为模块默认导入/no-anonymous-de 之前将对象分配给变量
- react-admin - 在 React-Admin 中扩展 JSON 服务器数据提供程序,因此更新不会在正文中发送 ID
- javascript - 表达自定义 json 响应
- javascript - 为什么更新全局对象变量不起作用?
- php - 如何检查一个数组的元素是否在另一个数组中
- windows - InfluxDBv2 - 获取远程配置作为 Telegraf Windows 服务