提问人:Horst Kretschmer 提问时间:9/5/2023 更新时间:9/5/2023 访问量:74
将 std::real 作为投影传递给 ranges::sort 不会编译
Passing std::real to ranges::sort as a projection doesn't compile
问:
我正在尝试通过传递 std::real 作为投影参数来按它们的实分量对复数向量进行排序,该参数无法编译。我似乎无法弄清楚原因,主要是因为编译错误非常冗长。
使用 lambda 有效,但很丑陋,我宁愿不这样做。一个类似的问题,按大小对向量的向量进行排序,编译并完美地工作。这是我尝试过的:
#include <bits/stdc++.h>
using namespace std;
typedef complex<double> cp;
int main() {
vector<cp> P = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4.2}};
ranges::sort(P, {}, real<double>); // doesn't compile
ranges::sort(P, {}, real<cp>); // doesn't compile
ranges::sort(P, {}, &cp::real); // doesn't compile
auto pj = [](cp a) {return real(a);};
ranges::sort(P, {}, pj); // compiles and works, but is ugly
vector<vector<int>> tst = {{1, 3}, {1, 4, 5}, {1}};
ranges::sort(tst, {}, size<vector<int>>); // compiles and works
ranges::sort(tst, {}, &vector<int>::size); // compiles and works
auto tstpj = [](vector<int>& a) {return size(a);};
ranges::sort(tst, {}, tstpj); // compiles and works, but is ugly
}
为什么带有复数的版本不起作用,我该如何解决?
答:
0赞
康桓瑋
9/5/2023
#1
一个类似的问题,按大小对向量的向量进行排序,编译和 完美工作。
但是,这是未指定的行为,除非标准指定它是可寻址函数,否则不允许直接获取标准库函数的地址。
在 C++20 中,更简单的方法是将自定义点对象作为投影:ranges::size
ranges::sort(tst, {}, ranges::size);
对于这种情况,使用 lambda 是最合适的选择。但是您可以使用宏来简化代码,例如:std::complex
#define MEMBER_FUN(memer_fun) \
[](auto&& x) -> decltype(auto) { return std::forward<decltype(x)>(x).memer_fun(); }
这样可以更轻松地构造调用对象成员函数的 lambda
vector<complex<double>> P = /* */;
ranges::sort(P, {}, MEMBER_FUN(real));
vector<vector<int>> tst = /* */;
ranges::sort(tst, {}, MEMBER_FUN(size));
评论
std::real<T>
&std::real<T>
std::real
ranges::sort(P, {}, [](cp a) { return real(a); });