std::sort

Started by
24 comments, last by daniel_i_l 18 years, 2 months ago
A while ago I posted problems with qsort() and was told to use std::sort. I did that and I still get some errors that I can't understand. I have a class unit:

class unit{
public:
 unit();
 int place_on_path,length_of_path;
 bool got_to_dest,path_found;
 int state;
 int formation_id;
 VERTEX position;
 VERTEX speed;
 float rotation;
 void init();
 void draw();
 void update();
 void InitPath();
 void FindSpeeds(grid now,grid next);
 grid path[500];
 grid current_step,next_step,offset; 
};

and a group class:

class player_group{
public:
 //typedef int (*compfn)(const void*, const void*);
 player_group();
 vector<unit>units;
 unit mid_pos;
 grid main_path[500];
 int place_on_path,length_of_path;
 int middle_man;
 
 ...
 
 void SortUnits(int method);
 bool SortDis( struct unit *elem1, struct unit *elem2);
 bool SortDisMid( struct unit *elem1, struct unit *elem2);
};

With the SortUnits function I want to sort the units vector according to the method. For example, inorder to sort them from closest to main_path to furthest from main_path I used the function:

bool player_group :: SortDis( struct unit *elem1, struct unit *elem2)
{
 if(  abs(elem1->next_step.x-main_path[place_on_path+step].x)+
      abs(elem1->next_step.y-main_path[place_on_path+step].y)
     <abs(elem2->next_step.x-main_path[place_on_path+step].x)+
      abs(elem2->next_step.y-main_path[place_on_path+step].y))			
      return FALSE;																					
   else										
      return TRUE;	
}

and then for the SortUnits I did:

void player_group :: SortUnits(int method)
{


  if(method==0)
  {
   sort(units.begin(), units.end(), SortDis());
  }
  if(method==1)
  {
  sort(units.begin(), units.end(), SortDisMid());
  }
}

But I got the error messages: PGroup.cpp C:\Dev-Cpp\Examples\ctf\PGroup.cpp In member function `void player_group::SortUnits(int)': 170 C:\Dev-Cpp\Examples\ctf\PGroup.cpp no matching function for call to `player_group::SortDis()' 55 C:\Dev-Cpp\Examples\ctf\PGroup.cpp candidates are: bool player_group::SortDis(unit*, unit*) What is the problem? Thanks!!
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
Advertisement
Your units vector is declared as std::vector<unit> not vector<unit *> so your sort predicate will expect the parameters to be unit, not unit*.
"Absorb what is useful, reject what is useless, and add what is specifically your own." - Lee Jun Fan
I changed the bool Sort functions to:

bool SortDis( struct unit elem1, struct unit elem2);

and changed the -> to '.' .
It still gave the same errors.
Thank.

EDIT: It looks from the errors that the problem is in the fact that I'm writing SortDis() without the elem1 and elem2 in the (), what should I do?
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
make your sort routines static or make them global to make it work. Sort requires a binary function, means 2 arguments. BUT if you declare a memberfunction nonstatic it has 3 arguments, of which one is hidden (the this pointer). Also a pointer to a memberfunction is a bit different than a pointer to a 'global' function...afaik thats also why people invented delegates, so they can call memberfunctions of instances of classes (but thats a different story...)

ok the next thing you should make is, if you are programming 'const' correct you should make the params const


edit: eww yes your edit indicates another 'error' std::sort(units.begin(), units.end(), yoursortfunc_without_brackets);


T2k
Thanks, can you show me with some code how I can make the sort function part of the player_group class so that I can use it's variables in the function?
Thanks.
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
There is code here for dealing with pointers to member functions (which is what you'll be passing), and plenty of other useful info too.
Here is a good (although somewhat long-winded) explanation of how to use std::sort...

http://www.thecodeproject.com/vcpp/stl/stdsort.asp

I read the link and did this:
struct SortDis : public player_group{ bool operator()(unit*& elem1, unit*& elem2)   {    return   abs(elem1->next_step.x-main_path[place_on_path+1].x)+             abs(elem1->next_step.y-main_path[place_on_path+1].y)          <  abs(elem2->next_step.x-main_path[place_on_path+1].x)+             abs(elem2->next_step.y-main_path[place_on_path+1].y) ;	   }};


I still got just about the same errors!? Does anyone know what the problem is?

Thanks!!
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
Quote:Original post by daniel_i_l
I read the link and did this:
*** Source Snippet Removed ***


Quote:Original post by JY
Your units vector is declared as std::vector<unit> not vector<unit *> so your sort predicate will expect the parameters to be unit, not unit*.


//BAD!!!              v               vbool operator()( unit * & elem1, unit * & elem2 )//BAD!!!              ^               ^//GOOD!!!            v             vbool operator()( unit & elem1, unit & elem2 )//GOOD!!!            ^             ^//EXTRA CREDIT!  vvvvv               vvvvv                vvvvvbool operator()( const unit & elem1, const unit & elem2 ) const//EXTRA CREDIT!  ^^^^^               ^^^^^                ^^^^^


/* Rationale: This is an issue of const correctness. consts #1 and #2 mean we
* won't modify our arguments, and thus it's OK to pass our function const
* objects. Non-const objects are also fine. Note that by doing this,
* assignments such as "elem1.next_step = ..." will generate compiler errors,
* since elem1 is const. This is to prevent a mistake - a good thing in this
* case! Const #3 tells the compiler that the function itself isn't modifying
* anything of it's owning class - thus this becomes legal:
*
* const SortDis sorter;
* bool unit1_before_unit2 = sorter( unit1 , unit2 );
*
* As is, the above code will fail, because operator() is not const, and thus
* cannot be called for a const SortDis (as sorter is).
*/

//BAD!!               vv             abs(elem1->blah)+             abs(elem1->blah)          <  abs(elem2->blah)+             abs(elem2->blah) ;	//BAD!!!              ^^//GOOD!!              v             abs(elem1.blah)+             abs(elem1.blah)          <  abs(elem2.blah)+             abs(elem2.blah) ;	//GOOD!!!             ^


[Edited by - MaulingMonkey on January 27, 2006 1:58:24 AM]
Thanks, now my program atleast compiles but I have another problem. Originally I stored the units in an array. Then I changed them to a vector and changed the sort function as you said, but now my program crashes. Is there anything else that I have to modify? (in general)
Thanks!
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky

This topic is closed to new replies.

Advertisement