Reputation: 15960
How to do that?
Thanks
Upvotes: 1
Views: 4969
Reputation: 414835
Boost.Bind allows in simple cases to define a compare function inplace:
#include <iostream>
#include <algorithm>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/bind.hpp>
#define P(a) do { \
BOOST_FOREACH (Struct s, a) \
std::cout << boost::format("(%d %c) ") % s.i % s.c; \
std::cout << std::endl; \
} while(0)
namespace {
struct Struct { int i; char c; };
}
int main() {
using boost::bind;
Struct a[] = { 1, 'z', 2, 'a' }; P(a);
const int N = sizeof(a) / sizeof(*a);
std::sort(a, a + N, bind(&Struct::i, _1) > bind(&Struct::i, _2)); P(a);
std::sort(a, a + N, bind(&Struct::c, _1) > bind(&Struct::c, _2)); P(a);
}
Output:
(1 z) (2 a)
(2 a) (1 z)
(1 z) (2 a)
Upvotes: 0
Reputation: 4476
Just for completeness, here is a an example using c++0x lambda functions:
std::vector<Person> v;
std::sort(v.begin(), v.end(), [](Person a, Person b) { return a.name_ < b.name_; });
...
std::sort(v.begin(), v.end(), [](Person a, Person b) { return a.address_ < b.address_; });
Upvotes: 1
Reputation: 208456
You can define what comparison function to use in each run of the sort algorithm by using the third argument:
template <class RandomAccessIterator, class StrictWeakOrdering>
void sort(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp);
A simple example:
struct person {
std::string name;
int age;
};
bool sort_by_name( const person & lhs, const person & rhs )
{
return lhs.name < rhs.name;
}
bool sort_by_age( const person & lhs, const person & rhs )
{
return lhs.age < rhs.age;
}
int main() {
std::vector<person> people;
// fill in the vector
std::sort( people.begin(), people.end(), sort_by_name );
std::sort( people.begin(), people.end(), sort_by_age );
}
Upvotes: 13
Reputation: 95639
There are two versions of std::sort, the first one simply takes the iterators and uses the object's operator< overload, while the second allows you to specify a comparator object to perform the comparison. You simply need to provide a class that conforms to the StrictWeakOrdering concept as a compartor. The comparator object (or function) should be callable with two parameters, where each parameters is of the specified type, and it should return true if the first parameter is less than the second parameter. For example:
bool mycomparator(const T& a, const T&b); // return true if a < b
OR
class MyComparator { public: bool operator()(const T& a, const T& b)const; // return true if a < b };
Upvotes: 1
Reputation: 523724
There are 2 versions of std::sort
, the 2nd version accepts a comparison functor:
template <class RandomAccessIterator, class StrictWeakOrdering>
void sort(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp);
//--------^^^^^^^^^^^^^^^^^^^^^^^
For example:
bool isLessThan(const MyStruct& first, const MyStruct& second) {
if (first.name < second.name) return true;
else if (first.name == second.name) {
if (first.date > second.date) return true;
// etc.
}
return false;
}
...
sort(v.begin(), v.end(), isLessThan);
See also http://www.cplusplus.com/reference/algorithm/sort/.
This variant still uses the same quicksort algorithm, so it's O(n log n) on average.
Upvotes: 2