C++ - 如何正确地将比较器传递给STL函数

Shi*_* Xu 3 c++ stl c++11

我写了一PointCollection堂课.

PointCollection 持有一堆积分.

它有2个成员函数.

addPoint(Point point)

findNearestKPoints(Point center, int k)

每次findNearestKPoints调用时,center都会指定a来查找k周围最近的k点.

但它无法编译:

error: called object type 'bool (PointCollection::*)(const Point &, const Point &) const' is not a function or function pointer

怎么做正确?

我的代码作为参考:

struct Point {
    int val_;
    Point() {}
    Point(int val) : val_(val) {}
};

class PointCollection {
private:
    vector<Point> points_;
    Point center_;
public:
    PointCollection() {}
    virtual ~PointCollection() {}

    void addPoint(const Point &point) {
        points_.push_back(point);
    }

    bool compare(const Point &a, const Point &b) const {
        return std::abs(a.val_ - center_.val_) < std::abs(b.val_ - center_.val_);
    }

    vector<Point> findNearestKPoints(Point center, int k) {
        center_ = center;

        nth_element(points_.begin(), points_.begin() + k - 1, points_.end(), 
                    &PointCollection::compare);

        return vector<Point>(points_.begin(), points_.begin() + k);
    }
};
Run Code Online (Sandbox Code Playgroud)

Sam*_*hik 8

比较器是可调用对象.换句话说:函数指针或lambda闭包,或具有合适的类operator().

&PointCollection::compare不是可调用的对象.这是一种课堂方法.它不是可调用的对象,原因很简单,您无法直接调用它.只能在类的实例上调用类方法.您必须在某处拥有此类的实例,并调用其compare()方法.它看起来像一个函数,但事实并非如此.这是一种课堂方法.

一个简单的解决方案是this通过lambda 捕获,类似于(C++ 14):

nth_element(points_.begin(), points_.begin() + k - 1, points_.end(),
              [this](const auto &a, const auto &b)
                  {
                      return this->compare(a, b);
                  });
Run Code Online (Sandbox Code Playgroud)

lambda捕获this,compare()可以调用this,就像它可以直接从父方法调用一样.

PS你findNearestKPoints()回来了vector<Point>,而不是vector<int>你声明的那样.

  • 那些人也可以将`auto`改为具体类型(在这种情况下为`Point`). (2认同)