Custom Sorting a vector of tuples

前端 未结 4 413
自闭症患者
自闭症患者 2021-02-04 04:22

I have a vector of tuples like

vector> v;

I believe that when the default comparison kicks in for tuple types, i

4条回答
  •  生来不讨喜
    2021-02-04 05:15

    There are many ways to do that, the one I use boils down to declaring a custom comparison object, actually the following

    // Functor to compare by the Mth element
    template class F = std::less>
    struct TupleCompare
    {
        template
        bool operator()(T const &t1, T const &t2)
        {
            return F::type>()(std::get(t1), std::get(t2));
        }
    };
    

    It works for tuples of arbitrary length (avoiding variadic templates - even though it's fairly easy and safer to do it the variadic way because you can declare the arguments of operator() as tuples of arbitrary length) and also works for pairs and you can pass it a custom comparison function/object but uses < operator as the default policy. An example usage would be

    int main()
    {
        vector> v;
        v.push_back(make_tuple(1, "Hello"));
        v.push_back(make_tuple(2, "Aha"));
    
        std::sort(begin(v), end(v), TupleCompare<0>());
        return 0;
    }
    

    there is ofcourse a more modern way, by using lambdas, so the sorting line would be

    std::sort(begin(v), end(v), 
        [](tuple const &t1, tuple const &t2) {
            return get<0>(t1) < get<0>(t2); // or use a custom compare function
        }
    );
    

    I believe it's worth making a function object for this (avoids a lot of boilerplate code) and go with the first approach


    EDIT

    As Yakk's comment (on c++1y) became standard compliant (c++14), we demonstrate below the case for generic lambdas

    std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
            return get<0>(t1) < get<0>(t2); // or use a custom compare function
    });
    

    which greatly matches the mechanics of TupleCompare since the operator() is templated as well.

提交回复
热议问题