STL list sort method-- can I pass in a class member function?

J

Jim Bancroft

I'm trying to roll a custom sort routine for an STL list. This list is a
member of one of my classes, and I'd like my custom sort to use another
class member in its calculations. However, I'm having trouble figuring out
if / how I can do this.

I've read this page about how to create a custom sort routine:

http://www.cplusplus.com/reference/stl/list/sort.html

However, in the example given the custom sort routine doesn't belong to a
particular class. When I created my own sort routine, as part of my class,
the compiler complains about my function call missing an argument list,
which sounds to me like the compiler simply doesn't like sort routines to be
part of a class--maybe I'm wrong.

This is what my custom sort routine's signature looks like:

bool Player::compare_verticies (Point first, Point second)

I call it like this, from within a class method in the "Player" class:

list<Point> pointList;
//populate list....
pointList.sort(compare_verticies);

The compiler tells me that "Player::compare_clockwise_verticies': function
call missing argument list; use '&Player::compare_clockwise_verticies' to
create a pointer to member".

I really need to refer to the class member in my custom sort routine, but I
don't see how I can do it if sort routines must be non-class methods. Does
anyone know what I can try here? Thanks very much.
 
D

Daniel T.

Jim Bancroft said:
I'm trying to roll a custom sort routine for an STL list. This list is a
member of one of my classes, and I'd like my custom sort to use another
class member in its calculations. However, I'm having trouble figuring out
if / how I can do this.

I've read this page about how to create a custom sort routine:

http://www.cplusplus.com/reference/stl/list/sort.html

However, in the example given the custom sort routine doesn't belong to a
particular class. When I created my own sort routine, as part of my class,
the compiler complains about my function call missing an argument list,
which sounds to me like the compiler simply doesn't like sort routines to be
part of a class--maybe I'm wrong.

This is what my custom sort routine's signature looks like:

bool Player::compare_verticies (Point first, Point second)

I call it like this, from within a class method in the "Player" class:

list<Point> pointList;
//populate list....
pointList.sort(compare_verticies);

The compiler tells me that "Player::compare_clockwise_verticies': function
call missing argument list; use '&Player::compare_clockwise_verticies' to
create a pointer to member".

I really need to refer to the class member in my custom sort routine, but I
don't see how I can do it if sort routines must be non-class methods. Does
anyone know what I can try here? Thanks very much.

class Player {
list< Point > pointList;
static bool compare_verticies( Point left, Point right ) {
// return true or false depending on if left < right or not
}
public:
void sort() {
pointList.sort( ptr_fun( &Player::compare_verticies ) );
}
};
 
J

Jim Bancroft

Thank you very much for the snippet. Unfortunately, I'd really like my
compare_verticies method to use a data member stored in Player. Because the
method is declared as static, I can't do that. And when I remove the static
modifier from compare_verticies I receive a number of compiler errors.

Is it feasible for my comparison method to use a data member in my class?
 
R

Ralph D. Ungermann

Daniel said:
> class Player {
> list< Point > pointList;
> static bool compare_verticies( Point left, Point right ) {
> // return true or false depending on if left < right or not
> }
> public:
> void sort() {
> pointList.sort( ptr_fun( &Player::compare_verticies ) );
> }
> };

Jim said:
Thank you very much for the snippet. Unfortunately, I'd really like my
compare_verticies method to use a data member stored in Player.

class Player does not store anything. Only instances do.
Because the method is declared as static, I can't do that.

Yes, you can. But as there is no invoking object (this), you have to
name the objects you want to access:

static bool compare_verticies( Point left, Point right )
{
// compare left.pointList to right.pointList
}

-- ralph
 
D

Daniel T.

Jim Bancroft said:
Thank you very much for the snippet. Unfortunately, I'd really like my
compare_verticies method to use a data member stored in Player. Because the
method is declared as static, I can't do that. And when I remove the static
modifier from compare_verticies I receive a number of compiler errors.

Is it feasible for my comparison method to use a data member in my class?

Things get a little more complicated then:

class Player {
friend class PointSorter;
class PointSorter {
Player* p;
public:
PointSorter( Player* p ): p(p) { }
bool operator()( Point left, Point right );
};

list< Point > pointList;
public:
void sort() {
pointList.sort( PointSorter( this ) );
}
};

bool PointSorter::eek:perator()( Point left, Point right ) {
// return true or false depending on if left < right or not
// use 'p' to help make the determination.
}
 
D

Daniel T.

If you are willing to use the Boost lambda library, you can also do
it like this:

class Player {
list< Point > pointList;

bool compare_verticies( Point left, Point right );
public:
void sort() {
pointList.sort( bind( &Player::compare_verticies, this, _1,
_2 ) );
}
};

bool Player::compare_verticies( Point left, Point right ) {
// return true or false depending on if left < right or not
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top