首页 > 解决方案 > 使用元素的投影而不是比较器进行排序

问题描述

我为此搜索了 c++ 模拟(python):

sorted(vector, key=lambda x : my_function(x))

当然还有构造:

std::sort(vector.begin(), vector.end(), [](const auto& lhs, const auto& rhs) {
    return my_function(lhs) < my_function(rhs);
});

我只是想知道是否存在单参数构造。

标签: c++sortingcomparatorprojection

解决方案


C++20 将在需要时使用范围而不是迭代器对。

除此之外,投影(结合用于反转顺序的标志)更简洁,其中作业是直截了当的,就像所有子键以相同的顺序排列,并且都根据它们的“自然”顺序排序。
比较器并没有针对这种情况进行不懈的优化,通过交易轻松实现全面的最佳性能,并轻松执行要求更高甚至完全怪异的订单。

Pythonsorted()只允许投影和可选的反向标志。

std::sort()可以根据自定义比较器对元素进行排序。原则上,如果它不能用作比较器,它可以扩展为尝试使用传递的函数对象(如果有的话)作为投影,请随意提出标准化。

除非发生这种情况,否则您可以轻松地从投影和顺序关系中综合比较:

template <class Projection, class Comparator = std::less<>>
struct use_projection {
    [[no_unique_address]] Projection p = Projection();
    [[no_unique_address]] Comparator c = Comparator();
    template <class... T>
    auto operator()(T&&... t) const
    noexcept(noexcept(c(p(std::forward<T>(t))...)))
    -> decltype(c(p(std::forward<T>(t))...))
    { return c(p(std::forward<T>(t))...); }
};

auto my_projection = [](auto&& x)->auto&& { return x.y; };
std::sort(v.begin(), v.end(), use_projection{my_projection});
std::sort(v.begin(), v.end(), use_projection{my_projection, std::greater()});

将这个想法改编为 C++17 之前的版本留给读者作为练习。


推荐阅读