Есть несколько разных объектов и несколько разных свойств, по которым можно было бы их отсортировать.
Хотя решение, опубликованное Эриком, является правильным, это утверждение заставляет меня думать, что в лучшем случае нецелесообразно, если вы на самом деле планируете сортировать по нескольким открытым элементам данных нескольких классов несколькими способами в одной программе в качестве каждого метода сортировки. потребуется собственный тип функтора.
Я рекомендую следующую абстракцию:
#include <functional>
template<typename T, typename M, template<typename> class C = std::less>
struct member_comparer : std::binary_function<T, T, bool>
{
explicit member_comparer(M T::*p) : p_(p) { }
bool operator ()(T const& lhs, T const& rhs) const
{
return C<M>()(lhs.*p_, rhs.*p_);
}
private:
M T::*p_;
};
template<typename T, typename M>
member_comparer<T, M> make_member_comparer(M T::*p)
{
return member_comparer<T, M>(p);
}
template<template<typename> class C, typename T, typename M>
member_comparer<T, M, C> make_member_comparer2(M T::*p)
{
return member_comparer<T, M, C>(p);
}
Использование будет выглядеть так:
#include <algorithm>
#include <vector>
#include <string>
struct MyClass
{
int i;
std::string s;
MyClass(int i_, std::string const& s_) : i(i_), s(s_) { }
};
int main()
{
std::vector<MyClass> vec;
vec.push_back(MyClass(2, "two"));
vec.push_back(MyClass(8, "eight"));
// sort by i, ascending
std::sort(vec.begin(), vec.end(), make_member_comparer(&MyClass::i));
// sort by s, ascending
std::sort(vec.begin(), vec.end(), make_member_comparer(&MyClass::s));
// sort by s, descending
std::sort(vec.begin(), vec.end(), make_member_comparer2<std::greater>(&MyClass::s));
}
Это будет работать для любого типа с общедоступными членами данных и сэкономит много печатания, если вам нужно сортировать свои классы несколькими способами.
Вот вариант, который работает с общедоступными функциями-членами вместо общедоступных элементов данных:
#include <functional>
template<typename T, typename M, template<typename> class C = std::less>
struct method_comparer : std::binary_function<T, T, bool>
{
explicit method_comparer(M (T::*p)() const) : p_(p) { }
bool operator ()(T const& lhs, T const& rhs) const
{
return C<M>()((lhs.*p_)(), (rhs.*p_)());
}
private:
M (T::*p_)() const;
};
template<typename T, typename M>
method_comparer<T, M> make_method_comparer(M (T::*p)() const)
{
return method_comparer<T, M>(p);
}
template<template<typename> class C, typename T, typename M>
method_comparer<T, M, C> make_method_comparer2(M (T::*p)() const)
{
return method_comparer<T, M, C>(p);
}
С использованием как:
#include <algorithm>
#include <vector>
#include <string>
class MyClass
{
int i_;
std::string s_;
public:
MyClass(int i, std::string const& s) : i_(i), s_(s) { }
int i() const { return i_; }
std::string const& s() const { return s_; }
};
int main()
{
std::vector<MyClass> vec;
vec.push_back(MyClass(2, "two"));
vec.push_back(MyClass(8, "eight"));
// sort by i(), ascending
std::sort(vec.begin(), vec.end(), make_method_comparer(&MyClass::i));
// sort by s(), ascending
std::sort(vec.begin(), vec.end(), make_method_comparer(&MyClass::s));
// sort by s(), descending
std::sort(vec.begin(), vec.end(), make_method_comparer2<std::greater>(&MyClass::s));
}