Sign in to follow this  
Calin

STL list

Recommended Posts

I have a list of user defined types and I am trying to figure out how to sort the list using the value of a cetain member of the class/structure.If I have a class 'Unit' that has a member 'Height'(float type) how do I sort a list of 'Unit' using 'Height' as the criteria? The tutorials I have read so far tell you to use operator overloading in the class declaration but I don't uderstand how you must do it in practice. Can anyone offer some suggestions? Thanks in advance.

Share this post


Link to post
Share on other sites
You don't need to use operator overloading. You just need a function that compares them that you pass to the std::list::sort() member function (assuming your compiler groks templated member functions).

Something like:

bool compare(const Unit & lhs, const Unit & rhs) {
return lhs.Height < rhs.Height;
}

std::list<Unit> units;

// fill units

units.sort(&compare);

Share this post


Link to post
Share on other sites
When you call list::sort() you can provide a comparison function. It's a bit obtuse for superficial stuff, but here's some example code:


#include <functional>
#include <list>

using namespace std;

struct Unit
{
int height;
Unit(int h) { height = h; }
};

struct SortByHeight : public binary_function<const Unit&, const Unit&, bool>
{
bool operator()(const Unit &lhs, const Unit &rhs)
{
return lhs.height < rhs.height;
}
};

void main()
{
Unit a(2), b(4), c(6), d(8);

list<Unit> unitList;

unitList.push_back(a);
unitList.push_back(b);
unitList.push_back(c);
unitList.push_back(d);

unitList.sort(SortByHeight());
}



Judiciously cribbed from this nearly identical forum post (found via Google).

Share this post


Link to post
Share on other sites
But doing it by operator overloading isn't really that hard either, and is the right thing to do when there is only one sorting method that makes sense for the class, or there is one that is a clear default - which generally goes hand in hand with the class having a natural ordering, i.e. a way to say that instance A is less than instance B or vice versa - which is exactly what you supply:


struct Unit {
int height;
Unit(int height) : height(height) {}
// Shame on you SImagery: use initializer lists! :)

// We provide the operator overload thusly:
bool operator< (const Unit& other) {
return height < other.height;
}
};

// Now we can call the 0-argument form of list::sort. It defaults to using
// std::less for comparison, which will in turn invoke your operator< - don't
// worry about performance; all of that gets inlined away.

list<Unit> mylist;
// fill the list...
mylist.sort();

Share this post


Link to post
Share on other sites
Two questions:
Do you want this list to always be sorted by this Height member?

If yes...

Have you ever used a std::set or std::multiset, or are you interested in learning how they might be even better than the list you're using?


Quote:
// Shame on you SImagery: use initializer lists! :)
I was going to remind Zahlman that he did copy from an example, but then I noticed that the example he copied from does use an initialiser list.
So instead I'll politely ditto Zahlman's comment:
[grin]Shame on you SImagery![grin]

Sorry[lol]

Share this post


Link to post
Share on other sites
Thank you all for help.

Quote:

iMalc:
Do you want this list to always be sorted by this Height member?


Generally speaking yes. The thing is I gave the height member as an example.
In my game I would like to sort my objects by their distance to the camera.
I need this for my picking function.

Quote:

iMalc:
Have you ever used a std::set or std::multiset, or are you interested in learning how they might be even better than the list you're using?


I will take a look on that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this