传递类的私有方法作为std :: sort的比较运算符 [英] Passing a private method of the class as the compare operator for std::sort

查看:191
本文介绍了传递类的私有方法作为std :: sort的比较运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

现在,我将调用 std :: sort 如下

  std :: sort(i.begin(),i.end比较); 

我希望得到所需的结果。但是代码不编译,我得到以下错误:

 错误:没有匹配的函数调用' :vector< long unsigned int> :: iterator,std :: vector< long unsigned int> :: iterator,< unresolved overloaded function type>)'

我必须正确完成所有的一切,因为 std :: sort 的文档提到我可以传递一个函数作为比较 std :: sort http: //www.cplusplus.com/reference/algorithm/sort/



感谢您提供的所有帮助。

解决方案

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

除此之外,您不能创建指向成员函数的指针,而不显式地获取其地址。 std :: sort(...,compare); 不会编译成员函数。虽然非成员函数会自动衰减到指向函数的指针,但这里并不是这样。



在C ++ 11中有两种不同的解决方案。最通用的是创建一个用于捕获参数的lambda:

  std :: sort(std :: begin(i),std :: end(i),
[](int x,int y){return compare(x,y);}); //或者甚至可以在这里实现

一个不同的方法是将对象和成员函数绑定到函数:

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

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



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


I am writing a code to solve the following problem: Given a set of numbers x[0], x[1], ..., x[N-1], find the permutation that makes them sorted in the ascending order. In the other words, I would like to find a permutation on {0,2,...,N-1} such as i[0], i[1], ..., i[N-1] such that x[i[0]] <= x[i[1]] <= ... <= x[i[N-1]].

For this, I have stored the x vector and an index vector i (initially filled with i[j] = j) as private members of a class. I have also defined a private method as

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

Now, I would call the std::sort as follows

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

and I expect to get the desired result. But the code does not compile and I get the following error:

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

I must have done everything correctly as also the documentation of std::sort mentions that I can pass a function as the compare operator to std::sort (http://www.cplusplus.com/reference/algorithm/sort/)

Thanks for all the helps in advance.

解决方案

There are a couple of issues with your approach. The first one and most evident is that you cannot use a member function as a free function. To be able to call compare you need an object of type MyClass and two integers. Inside std::sort the implementation is going to try to call a free (non-member) function with only two integer arguments.

Other than that, you cannot create a pointer to a member function without explicitly taking its address. The line std::sort(..., compare); will not compile for a member function. While non-member functions will automatically decay to a pointer to the function that is not the case here.

In C++11 there are two different solutions that you can take. The most generic is creating a lambda that captures the this argument:

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

A different approach would be binding the object and the member function into a functor:

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

In this last case, the std::bind function will create an object that implements operator() taking two arguments and will call the member function MyClass::compare on the object pointed by this.

The semantics of both approaches are slightly different, but in this case you can use either one.

这篇关于传递类的私有方法作为std :: sort的比较运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆