I'd use Boost Phoenix:
#include <boost/phoenix.hpp>
#include <list>
namespace phx = boost::phoenix;
using namespace phx::arg_names;
struct MyStruct { int a; int b; };
int main()
{
std::list<MyStruct> myList;
//...
myList.sort(phx::bind(&MyStruct::a, arg1) < phx::bind(&MyStruct::b, arg2));
}
Note that it seems extremely weird to be comparing different fields (unless the fields have some guaranteed redundancy relation (e.g.: they are always equal) it will not satisfy the requirements for a Strict Weak Total Ordering - required for most STL containers/algorithms that take a comparer.
To avoid both
- the verbosity of the comparator, as well as
- the risk of having different accesors on the left-hand/right-hand sides
I usually use a helper (c++03):
#include <boost/bind.hpp>
#include <list>
template <typename F>
struct compare_by_impl {
compare_by_impl(F f = F()) : _f(f) {}
template <typename T, typename U>
bool operator()(T const& a, U const& b) const {
return _f(a) < _f(b);
}
private:
F _f;
};
template <typename Accessor>
compare_by_impl<Accessor> comparer_by(Accessor f) {
return compare_by_impl<Accessor>(f);
}
struct MyStruct { int a; int b; };
int main()
{
std::list<MyStruct> myList;
//...
myList.sort(comparer_by(boost::mem_fn(&MyStruct::a)));
}
This no longer uses Boost Phoenix. See it Live on Coliru.
See a more up-to-date c++11 version here: How to implement a lambda function for a sort algorithm involving object members, indirection, and casting?