Compare function in a class for std::sort can't compile

c++, sorting, stl

Solution

The problem is that your `cmp` method needs to be `static`. The reason is that non-static methods expect an invisible first argument, the `this` pointer. The `std::sort` function do not pass this extra argument.

Since you reference member variables you can't make the function `static`, but there are other ways to solve this. I recommend using a new C++11 standard functionality, `std::bind`:

std::sort(a, a+n, std::bind(&ConvexHull::cmp, this));

The `std::bind` call creates a callable object, setting the first parameter to `this` so it will be correct when being called.

Problem

I'm writing a program to get a convex hull. I need to sort the points by polar angle, and I chose a `base` point before, so I write a member compare function ( notice that, for each object the `base` point is different ). But when I'm applying it to the `std::sort`, the program can't compile. Here is my program: ``` class ConvexHull { Point p[MAXN], base; public: int size; void Create(Point (&)[MAXN], const int); bool cmp(const Point& a, const Point& b) const { static int tmp; return (tmp = CrossProduct(base, a, base, b)) < 0 || (tmp == 0 && Dist(base, a) < Dist(base, b)); } }; void ConvexHull::Create(Point (&a)[MAXN], const int n) { base = a[0]; for (int i = 1; i < n; ++i) if (a[i].x < base.x || (a[i].x == base.x && a[i].y < base.y)) base = a[i]; std::sort(a, a+n, cmp); p[0] = a[0], p[1] = a[1]; size = 2; for (int i = 2; i < n; ++i) { while (size >= 2 && CrossProduct(a[i], p[size-1], a[i], p[size-2]) <= 0) --size; p[size++] = a[i]; } p[size++] = p[0]; } ``` and here is the error: ``` poj1113.cc: In member function 'void ConvexHull::Create(Point (&)[1000], int)': poj1113.cc:41:24: error: no matching function for call to 'sort(Point [1000], Point*, <unresolved overloaded function type>)' poj1113.cc:41:24: note: candidates are: In file included from /usr/include/c++/4.7/algorithm:63:0, from poj1113.cc:3: /usr/include/c++/4.7/bits/stl_algo.h:5463:5: note: template<class _RAIter> void std::sort(_RAIter, _RAIter) /usr/include/c++/4.7/bits/stl_algo.h:5463:5: note: template argument deduction/substitution failed: poj1113.cc:41:24: note: candidate expects 2 arguments, 3 provided In file included from /usr/include/c++/4.7/algorithm:63:0, from poj1113.cc:3: /usr/include/c++/4.7/bits/stl_algo.h:5499:5: note: void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = Point*; _Compare = bool (ConvexHull::*)(const Point&, const Point&)const] /usr/include/c++/4.7/bits/stl_algo.h:5499:5: note: no known conversion for argument 3 from '<unresolved overloaded function type>' to 'bool (ConvexHull::*)(const Point&, const Point&)const' ``` How to fix it? And is this ( I mean make the `base` member ) a bad deisgn?

Original source