Passing a private method of the class as the compare operator for std::sort

强颜欢笑 提交于 2019-12-05 16:19:43

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.

izomorphius Support Monica

Please keep in mind instance methods have an implicit first parameter - the this pointer of the object. Thus your comparison operator is not of the type expected by std::sort - it takes three arguments instead of the expected 2. Use a bind function to get around this(for instance boost::bind). Take a look at this question for instance.

cpp

One way round this problem is to define a function call operator in your class (see here):

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

Then you can invoke sort() method like this:

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

I just want to comment that the answer of @dribeas didn't work for me. I'm using the lambda function, and I had to edit it:

 std::sort(MyVector.begin(), MyVector.end(),
      [this](int x, int y) { return compare(x,y); });
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!