tags:

views:

651

answers:

5

How does one go about sorting a vector containing custom (i.e. user defined) objects.
Probably, standard STL algorithm sort along with a predicate (a function or a function object) which would operate on one of the fields (as a key for sorting) in the custom object should be used.
Am I on the right track?

+6  A: 

You could use functor as third argument of std::sort, or you could define operator< in your class.

struct X {
    int x;
    bool operator<( const X& val ) const { 
     return x < val.x; 
    }
};

struct Xgreater
{
    bool operator()( const X& lx, const X& rx ) const {
     return lx.x < rx.x;
    }
};

int main () {
    std::vector<X> my_vec;

    // use X::operator< by default
    std::sort( my_vec.begin(), my_vec.end() );

    // use functor
    std::sort( my_vec.begin(), my_vec.end(), Xgreater() );
}
Kirill V. Lyadvinsky
A: 

In your class, you may overload the "<" operator.

BobbyShaftoe
+2  A: 

You are on the right track. std::sort will by default use operator< as comparison function. So in order to sort your objects, you will either have to overload bool operator<( const T&, const T& ) or provide a functor that does the comparison, much like this:

 struct C {
    int i;
    static bool before( const C& c1, const C& c2 ) const { return c1.i < c2.i; }
 };

 bool operator<( const C& c, const C& c2 ) { return c1.i > c2.i; }

 std::vector<C> values;

 std::sort( values.begin(), values.end() ); // uses operator<
 std::sort( values.begin(), values.end(), C::before );

The advantage of the usage of a functor is that you can use a function with access to the class' private members.

xtofl
Missed that one: provide a member function operator<.
xtofl
Good example. +1
Ankur
It is better to make `operator<` a member of class (or struct), because global one could use protected or private members. Or you should make it a friend of struct C.
Kirill V. Lyadvinsky
A: 

Yes, std::sort() with third parameter (function or object) would be easier. An example:
http://www.cplusplus.com/reference/algorithm/sort/

swatkat
+6  A: 

A simple example:

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}
};

struct less_than_key
{
    inline bool operator() (const MyStruct& struct1, const MyStruct& struct2)
    {
        return (struct1.key < struct2.key);
    }
};

std::vector < MyStruct > vec;

vec.push_back(MyStruct(4, "test"));
vec.push_back(MyStruct(3, "a"));
vec.push_back(MyStruct(2, "is"));
vec.push_back(MyStruct(1, "this"));

sort(vec.begin(), vec.end(), less_than_key());


Edit: As Kirill V. Lyadvinsky pointed out, instead of supplying a sort predicate, you can override the < operator in MyStruct:

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}

    bool operator < (const MyStruct& str) const
    {
        return (key < str.key);
    }
};

Using this method means you can simply sort the vector as follows:

sort(vec.begin(), vec.end());
Alan
Thanks. +1 for a good example. This is where I was heading.
Ankur