如何在这个类中使用成员函数调用stl :: nth_element?

时间:2015-11-16 09:32:52

标签: c++ stl member-function-pointers nth-element

我希望在一个类中使用函数nth_element和我自己的排序函数(它应该可以访问对象的数据)。目前,我正在做以下事情:

class Foo
{
 public:
   glm::vec3 *points;
   int nmbPoints;

   bool idxPointCompareX(int a, int b);
   void bar();
}

bool Foo::idxPointCompareX(int a, int b)
{return points[a].x < points[b].x;)

void Foo::bar()
{
   stl::vector<int> idxPointList;
   for(int i = 0; i < nmbPoints; i++) idxPointList.push_back(i);  

   stl::nth_element(idxPointList.first(),idxPointList.first()+nmbPoints/2,idxPointList.end(), idxPointCompareX);
}

当然,这不起作用,我得到错误:“必须调用非静态成员函数的引用”。之后,我在这里查看了Reference to non-static member function must be calledHow to initialize std::function with a member-function?和其他一些问题。我理解为什么这不起作用,但我不确定如何解决这个问题。

有人可以帮助我并告诉我如何解决这个问题吗?

3 个答案:

答案 0 :(得分:6)

要获取成员函数的地址,您需要使用正确的语法,即&Foo::idxPointCompareX而不仅仅是idxPointCompareX

但是你还需要一个Foo对象来调用该函数,所以你需要将一个绑定到它。大概你的意思是在this上调用它,这样你就可以使用std::bind

using namespace std::placeholders;
stl::nth_element(begin, end, std::bind(&Foo::idxPointCompareX, this, _1, _2));

或者更简单,使用lambda函数:

stl::nth_element(begin, end, 
                 [this](int a, int b) { return idxPointCompareX(a, b);}
);

这将创建一个lambda函数,该函数捕获this并将其参数传递给捕获的this指针上的idxPointCompareX函数。

答案 1 :(得分:2)

idxPointCompareX是一个成员函数,即如果没有对Foo对象的引用则无法调用它。看看它的定义,似乎它不需要成为一个成员,因为它纯粹是根据它的论点定义的。

您可以将其设为static函数(即“类函数”)或自由函数,然后将其传递给std::nth_element

答案 2 :(得分:0)

您无法在创建对象方法之前调用它,因此您可以在此处选择一些选项:

  1. 使方法成为静态

  2. 将构造函数保留为空并将其全部移至init方法中,然后调用比较部分

  3. 使用lambda

  4. 示例:

    静态方法:

    static bool idxPointCompareX(glm::vec3 a, glm::vec3 b)
    {return a.x < b.x;)
    

    Init方法:

    Foo::bar()
    {
       stl::vector<int> idxPointList;
       for (int i = 0; i < nmbPoints; i++)
           idxPointList.push_back(i);  
    }
    
    Foo::init()
    {
        stl::nth_element(idxPointList.first(),
                         idxPointList.first()+nmbPoints/2,idxPointList.end(),
                         idxPointCompareX);
    }
    

    LAMBDA:

    Foo::bar()
    {
       stl::vector<int> idxPointList;
       for (int i = 0; i < nmbPoints; i++)
           idxPointList.push_back(i);  
    
       stl::nth_element(idxPointList.first(),
                        idxPointList.first()+nmbPoints/2,idxPointList.end(),
                        [](int a, int b){return points[a].x < points[b].x;));
    }
    

    我会自己去找lambda版本。