如何用这个class里面的成员函数调用stl::nth_element?
How to call stl::nth_element with a member function inside this class?
我想在 class 中将函数 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 called"。在那之后,我看了 Reference to non-static member function must be called, How to initialize std::function
with a member-function? 和其他一些问题。我明白为什么这不起作用,但我不确定如何解决这个问题。
有人可以帮助我并告诉我如何解决这个问题吗?
idxPointCompareX
是一个成员函数,即如果不引用 Foo
对象就不能调用它。不过看看它的定义,它似乎不需要成为成员,因为它纯粹是根据其参数定义的。
您可以将其设为 static
函数(即 "class function")或自由函数,然后将其传递给 std::nth_element
。
要获取成员函数的地址,您需要使用正确的语法,即 &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);}
);
这将创建一个捕获 this
并将其参数传递给捕获的 this
指针上的 idxPointCompareX 函数的 lambda 函数。
你不能在对象创建之前调用它的方法,所以你有一些选择:
使方法静态化
将构造函数留空并将所有内容移至调用比较部分的 init
方法中
使用 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 版本。
我想在 class 中将函数 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 called"。在那之后,我看了 Reference to non-static member function must be called, How to initialize std::function
with a member-function? 和其他一些问题。我明白为什么这不起作用,但我不确定如何解决这个问题。
有人可以帮助我并告诉我如何解决这个问题吗?
idxPointCompareX
是一个成员函数,即如果不引用 Foo
对象就不能调用它。不过看看它的定义,它似乎不需要成为成员,因为它纯粹是根据其参数定义的。
您可以将其设为 static
函数(即 "class function")或自由函数,然后将其传递给 std::nth_element
。
要获取成员函数的地址,您需要使用正确的语法,即 &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);}
);
这将创建一个捕获 this
并将其参数传递给捕获的 this
指针上的 idxPointCompareX 函数的 lambda 函数。
你不能在对象创建之前调用它的方法,所以你有一些选择:
使方法静态化
将构造函数留空并将所有内容移至调用比较部分的
init
方法中使用 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 版本。