将 std::real 作为投影传递给 range::sort 无法编译

问题描述 投票:0回答:1

我试图通过传递 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
}

为什么复数版本不起作用,如何修复?

c++ c++20 projection complex-numbers std-ranges
1个回答
0
投票

类似的问题,按大小对向量的向量进行排序,编译并 完美运作。

但是,这是未定义的行为,不允许直接获取标准库函数的地址,除非标准指定它是一个可寻址函数

在C++20中,更简单的方法是采用自定义点对象

ranges::size
作为投影:

ranges::sort(tst, {}, ranges::size);

对于

std::complex
的情况,使用lambda仍然是最合适的选择。但你可以用宏来简化代码,例如:

#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));
© www.soinside.com 2019 - 2024. All rights reserved.