Как вызвать stl :: 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);
}

Конечно, это не сработало, и я получил ошибку: «должна быть вызвана ссылка на нестатическую функцию-член». После этого я посмотрел на Ссылка на нестатическую функцию-член должна быть вызвана, Как инициализировать std::function с функцией-членом? и некоторые другие вопросы здесь. Я понимаю, почему это не сработало, но я не уверен, как это решить.

Может кто-нибудь мне помочь и подсказать, как решить эту проблему?

0

Решение

Чтобы получить адрес функции-члена, вам нужно использовать правильный синтаксис, т.е. &Foo::idxPointCompareX не просто idxPointCompareX

Но вам также нужно Foo объект для вызова функции, поэтому вам необходимо привязать его к ней. Предположительно вы хотите позвонить на this чтобы вы могли использовать std::bind:

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

Или проще, используйте лямбда-функцию:

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

Это создает лямбда-функцию, которая захватывает this и передает свои аргументы в функцию idxPointCompareX на захваченном this указатель.

5

Другие решения

idxPointCompareX является функцией-членом, т.е. она не может быть вызвана без какой-либо ссылки на Foo объект. Глядя на его определение, кажется, что он не должен быть членом, поскольку он чисто определен в терминах своих аргументов.

Вы могли бы сделать это static функция (то есть «функция класса») или свободная функция, а затем передать его std::nth_element,

2

Вы не можете вызвать метод объекта до того, как он будет создан, поэтому у вас есть несколько вариантов здесь:

  1. Сделайте метод статичным

  2. Оставьте конструктор пустым и переместите все в init метод, в котором вы вызываете часть сравнения

  3. Используйте лямбду

Примеры:

Статический метод:

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

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

Я бы сам пошел на лямбда-версию.

0
По вопросам рекламы [email protected]