传递类的私有方法作为std :: sort的比较运算符

时间:2013-08-16 13:03:18

标签: c++ sorting std

我正在编写一个代码来解决以下问题:给定一组数字x[0]x[1],...,x[N-1],找到使它们排序的排列升序。换句话说,我想在{0,2,...,N-1}上找到排列,例如i[0]i[1],...,i[N-1]这样的排列x[i[0]] <= x[i[1]] <= ... <= x[i[N-1]]

为此,我将x向量和索引向量i(最初用i[j] = j填充)存储为类的私有成员。我还将私有方法定义为

bool MyClass::compare(size_t s, size_t t) {
    return (x[s] < x[t]);
}

现在,我会按如下方式调用std::sort

std::sort(i.begin(), i.end(), compare);

我希望得到理想的结果。但代码无法编译,我收到以下错误:

error: no matching function for call to ‘sort(std::vector<long unsigned int>::iterator, std::vector<long unsigned int>::iterator, <unresolved overloaded function type>)’

我必须正确完成所有操作,同时提及std::sort提及我可以将函数作为比较运算符传递给std::sorthttp://www.cplusplus.com/reference/algorithm/sort/

的文档

提前感谢所有帮助。

4 个答案:

答案 0 :(得分:9)

您的方法存在一些问题。第一个也是最明显的是你不能使用成员函数作为自由函数。为了能够调用compare,您需要一个MyClass类型的对象和两个整数。在std::sort内部,实现将尝试仅使用两个整数参数调用 free (非成员)函数。

除此之外,如果不显式获取其地址,则无法创建指向成员函数的指针。行std::sort(..., compare);不会为成员函数编译。虽然非成员函数会自动衰减到指向函数的指针,但不是这里的情况。

在C ++ 11中,您可以采用两种不同的解决方案。最通用的是创建一个捕获this参数的lambda:

std::sort(std::begin(i),std::end(i),
          [](int x, int y) { return compare(x,y); }); // or maybe even implement here

另一种方法是将对象和成员函数绑定到仿函数中:

std::sort(std::begin(i),std::end(i),
          std::bind(&MyClass::compare,this,_1,_2));

在最后一种情况下,std::bind函数将创建一个实现operator()的对象,它接受两个参数,并将在MyClass::compare指向的对象上调用成员函数this

两种方法的语义略有不同,但在这种情况下,您可以使用其中任何一种方法。

答案 1 :(得分:1)

请记住,实例方法有一个隐含的第一个参数 - 对象的this指针。因此,您的比较运算符不是std::sort所期望的类型 - 它需要三个参数而不是预期的2.使用bind函数来解决此问题(例如boost::bind)。例如,请查看this question

答案 2 :(得分:0)

解决此问题的一种方法是在类中定义函数调用运算符(see here):

bool MyClass::operator() (size_t s, size_t t) {
    return (x[s] < x[t]);
}

然后你可以像这样调用sort()方法:

sort(i.begin(), i.end(), *this);

答案 3 :(得分:0)

我只是想评论@dribeas的答案对我不起作用。我使用lambda函数,我不得不编辑它:

 std::sort(MyVector.begin(), MyVector.end(),
      [this](int x, int y) { return compare(x,y); });