c++ std::sort():仅使用一个比较函数的任何可比较成员的对象向量

c++ std::sort() a vector of objects by any comparable member using only one compare function

本文关键字:向量 函数 任何 可比较 比较 成员 对象 sort std c++ 一个      更新时间:2023-10-16

是否有可能在对象的std::vector上调用std::sort(),这样我们就可以指定使用哪个成员来比较对象,而不必为每个成员实现单独的比较函数?我们可以假设我们要排序的每个成员都定义了<操作符。如果不是,当我们希望能够根据许多不同的标准对对象的容器进行排序时,最好的方法是什么?

可以有一个比较对象,该比较对象有一个标志,指示对哪个成员进行排序。

class Comparo
{
    int m_field;
public:
    Comparo(int field)  : m_field(field) { }
    bool operator()(const MyClass & Left, const MyClass & right)
    {
        switch (m_field)
        {
            case 0:
                return left.A < right.A;
            case 1:
                return left.B < right.B;
        }
    }
};
std::vector<MyClass> vec = FillMyVector();
std::sort(vec.begin(), vec.end(), Comparo(0));  // sorts on field A
std::sort(vec.begin(), vec.end(), Comparo(1));  // sorts on field B

下面的程序使用任意类的任意多个成员进行字典顺序比较。需要c++ 14的可变模板和编译时整数序列。如果你有c++ 11,你可以自己实现编译时的整数序列。

#include <tuple>
#include <utility> // for make_index_sequence
template<class T, typename... types>
struct member_comparer {
    member_comparer(types T::*...  args) : ptrs(args...) { }
    bool operator()(const T& t1, const T& t2) const {
        return do_compare(t1, t2, std::make_index_sequence<sizeof...(types)>());
    }
    private:
    template<size_t... indices>
    bool do_compare(const T& t1, const T& t2, std::index_sequence<indices...> ) const {
        return std::tie(t1.*std::get<indices>(ptrs)...) <
               std::tie(t2.*std::get<indices>(ptrs)...);
    }
    std::tuple<types T::* ...> ptrs;
};
template<class T, typename... types>
auto make_member_comparer(types T::*...  args) {
    return member_comparer<T, types...>(args...); 
}

你可以这样使用:

struct A {
    int x;
    double y;
    float z;
};
auto compare_x_only = make_member_comparer(&A::x);
auto compare_y_then_x = make_member_comparer(&A::y, &A::x);

演示。