【问题标题】:c++ std::sort() a vector of objects by any comparable member using only one compare functionc++ std::sort() 任何可比较成员仅使用一个比较函数的对象向量
【发布时间】:2014-07-20 03:56:02
【问题描述】:

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

【问题讨论】:

    标签: c++ sorting vector stl


    【解决方案1】:

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

    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
    

    【讨论】:

    • 太棒了。甚至没有想过给函子一个构造函数。
    【解决方案2】:

    这是一个使用任意类的任意多个成员进行字典比较的东西。可变参数模板和编译时整数序列需要 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);
    

    Demo.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-02
      • 2015-03-04
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-13
      相关资源
      最近更新 更多