根据对象

时间:2016-02-22 07:13:11

标签: c++ sorting c++11

我想根据元素的成员函数值对某些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没有比较运算符,或者它有一个,但我想根据另一个进行排序。

2 个答案:

答案 0 :(得分:3)

继续对OP的评论;您可以将lambda重构为自己的仿函数以使用std::sort,或者您可以通过将std::greaterstd::mem_fun与一个绑定(可能{{1}组合使用来使用C ++ 03样式某种等等。但是,使用C ++ 03样式会很麻烦。

仿函数解决方案要求调用操作符(std::bind)具有适当的签名;接受所需的值并返回operator()bool方法和const参数不需要,但按惯例通常会显示。

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()); 功能的float返回功能将按预期与area()一起使用。

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

operator >

在这种情况下,C ++ 03风格很难创建和使用,我不会在这条路上走得太远。

答案 1 :(得分:3)

您可以为此创建一个类:

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));

Demo