根据对象的成员函数进行排序

Sort depending on member function of the object

本文关键字:排序 函数 成员 对象      更新时间:2023-10-16

我想根据元素的成员函数值对一些vector进行排序,如下所示:

std::vector<cv::Rect> regions;
std::sort(begin(regions), end(regions), [](cv::Rect const& l, cv::Rect const& r){
  return l.area() > r.area();
});

我可以在不直接编写比较的情况下做到这一点吗?我可以想象这样的事情:

std::sort(begin(regions), end(regions), std::compare_greater<cv::Rect::area>);//imaginary code

有这样的事情吗?

编辑: cv::Rect::area 是一个返回 float 的成员函数。 cv::Rect没有比较运算符,或者它有一个,但我想根据另一个运算符进行排序。

继对OP的评论之后; 您可以将lambda重构为自己的函子以使用std::sort,或者您可以通过组合std::greater来使用C++03样式,std::mem_fun与某种绑定(可能是std::bind)等; 不过,C++03样式使用起来会很麻烦。

函子解要求调用运算符(operator())具有适当的签名;接受所需的值并返回boolconst方法和const&参数是不需要的,但按照惯例通常会出现。

struct compare_rect_greater {
  bool operator()(cv::Rect const& l, cv::Rect const& r) const
  {
    return l.area() > r.area();
  }
};
// ...
std::vector<cv::Rect> regions;
std::sort(begin(regions), end(regions), compare_rect_greater());

area()函数的float返回将按预期与operator >一起工作。

但是考虑到语言水平、易读性等,您的 lambda 仍然是更好的解决方案。

std::vector<cv::Rect> regions;
std::sort(begin(regions), end(regions), [](cv::Rect const& l, cv::Rect const& r){
  return l.area() > r.area();
});

在这种情况下,C++03 样式的创建和使用起来很笨拙,我不会在这条路上冒险太远。

你可以为此创建一个类:

template <typename Member>
struct greater_member;
template <typename C, typename Method>
class greater_member<Method (C::*)>
{
    explicit greater_member(Method (C::* method)) : mMethod(method) {}
    bool operator()(const C& lhs, const C& rhs) const
    {
        return (lhs.*mMethod)() > (rhs.*mMethod)();
    }
private:
    Method (C::* mMethod);
}
template <typename C, typename Method>
greater_member<Method (C::*)> make_greater_member(Method (C::* method))
{
    return greater_member<Method (C::*)>(method);
}

然后

std::sort(begin(regions), end(regions), make_greater_member(&cv::Rect::area));

演示