1

我想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);
}

当然,这不起作用,我得到了错误:“必须调用对非静态成员函数的引用”。之后,我查看了必须调用非静态成员函数的引用如何std::function使用成员函数进行初始化?和其他一些问题在这里。我明白为什么这不起作用,但我不确定如何解决这个问题。

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

4

3 回答 3

6

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

但是您还需要一个Foo对象来调用该函数,因此您需要将一个对象绑定到它。大概您的意思是调用它,this以便您可以使用std::bind

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

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

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

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

于 2015-11-16T09:39:57.457 回答
2

idxPointCompareX是一个成员函数,即它不能在没有对某个Foo对象的引用的情况下被调用。不过从它的定义来看,它似乎不需要成为成员,因为它纯粹是根据它的论点来定义的。

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

于 2015-11-16T09:35:13.760 回答
0

您不能在创建对象方法之前调用它,因此您有一些选择:

  1. 使方法静态

  2. 将构造函数留空并将所有内容移到init调用比较部分的方法中

  3. 使用 lambda

例子:

静态方法:

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

初始化方法:

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

拉姆达:

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 版本。

于 2015-11-16T09:43:35.833 回答