4

我正在编写一个代码来解决以下问题:给定一组数字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

4 回答 4

9

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

除此之外,您不能在不明确获取其地址的情况下创建指向成员函数的指针。该行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

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

于 2013-08-16T13:15:04.040 回答
1

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

于 2013-08-16T13:07:55.053 回答
0

解决此问题的一种方法是在您的类中定义一个函数调用运算符(请参见此处):

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

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

sort(i.begin(), i.end(), *this);
于 2013-08-16T13:15:21.590 回答
0

我只想评论@dribeas 的答案对我不起作用。我正在使用 lambda 函数,我必须对其进行编辑:

 std::sort(MyVector.begin(), MyVector.end(),
      [this](int x, int y) { return compare(x,y); });
于 2014-06-02T20:34:55.650 回答