2

How should I pass a function inside an struct as a functor? I assumed this should work fine, but it didn't:

#include <algorithm>
using namespace std;

struct s {
    int a[10];

    bool cmp(int i, int j) {
        // return something
    }

    void init() {
        sort(a, a + 10, cmp);
    }
};

which gets <unresolved overloaded function type>

semekh
  • 3,867
  • 2
  • 24
  • 34

2 Answers2

6

You cannot do this directly, because cmp is a member function, which requires three arguments: i, j, and the invisible, implicit this pointer.

To pass cmp to std::sort, make it a static function, which does not belong to any particular instance of s and thus doesn't have a this pointer:

static bool cmp(int i, int j) {
    // return something
}

If you need access to this, you can wrap cmp in a simple function object instead:

struct cmp {
    s &self;
    cmp(s &self) : self(self) { }
    bool operator()(int i, int j) {
        // return something, using self in the place of this
    }
};

And call it like this:

sort(a, a + 10, cmp(*this));
Thomas
  • 174,939
  • 50
  • 355
  • 478
  • Why are we using static for this? What does this do? – template boy Nov 24 '12 at 16:27
  • 1
    @typedeftypename a static member function is basically a free function in a namespace that just happens to actually be the class. – leftaroundabout Nov 24 '12 at 16:28
  • @typedeftypename: `static` makes it disappear this implicit `this` from the requirements. With it, the function needs just two arguments, `i` and `j`, which are all there. – Nawaz Nov 24 '12 at 16:28
2

While @Thomas answer is completely working, You may even do it simpler using std::bind or lambdas as follow:

// Using std::bind
std::sort( a, a + 10, std::bind(&s::cmp, this, _1, _2) );

// Using lambdas
std::sort( a, a + 1, [this](int i, int j) {return this->cmp( i, j );} );
BigBoss
  • 6,904
  • 2
  • 23
  • 38
  • Wow, great! I suppose this should be the c++0x magic. Too bad I can't use it in my situation. – semekh Nov 24 '12 at 16:59
  • You may use `boost::bind` in place of `std::bind`, actually I'm currently using it for this purpose! – BigBoss Nov 24 '12 at 17:01