Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用元素的投影而不是比较器进行排序 我搜索了C++模拟(Python):_C++_Sorting_Comparator_Projection - Fatal编程技术网

使用元素的投影而不是比较器进行排序 我搜索了C++模拟(Python):

使用元素的投影而不是比较器进行排序 我搜索了C++模拟(Python):,c++,sorting,comparator,projection,C++,Sorting,Comparator,Projection,当然,这里有一个结构: std::sort(vector.begin(), vector.end(), [](const auto& lhs, const auto& rhs) { return my_function(lhs) < my_function(rhs); }); std::sort(vector.begin()、vector.end()、[](常量自动和lhs、常量自动和rhs){ 返回my_函数(lhs)自动和&{return x.y;}; 排序(

当然,这里有一个结构:

std::sort(vector.begin(), vector.end(), [](const auto& lhs, const auto& rhs) {
    return my_function(lhs) < my_function(rhs);
});
std::sort(vector.begin()、vector.end()、[](常量自动和lhs、常量自动和rhs){
返回my_函数(lhs)

我只是想知道是否存在一个参数结构。

如果我正确理解了这个问题,您会问标准库中是否有一个排序函数,它根据给定的键而不是比较器进行排序

标准库中没有类似的内容。在Python中,由于对象是基于表的——由于结构或记录的基本概念最终在语言中实现为字符串键和可能是函数的值之间的映射——因此可以简洁地将字段称为字符串。在C++中,情况并非如此。如果你有一个

struct Foo {
    std::string name;
    int id;
};
正在运行的程序不知道字段名“name”和“id”;它们仅作为源代码的工件存在。因此,要执行类似于基于Python键的排序的操作,您需要提供一个函数(或者一个可调用的对象)来从每个项中提取您想要使用的键值

类似于以下内容的操作将起作用:

template<typename Iter, typename Func>
void sort_by_key(Iter from, Iter to, Func get_key) {
    std::sort(from, to, 
        [get_key](auto lhs, auto rhs) {
            return get_key(lhs) < get_key(rhs);
        }
    );
}

struct Foo {
    std::string name;
    int id;
};

...

std::vector<Foo> foobar{ {"quux", 10000}, {"mumble", 12}, {"frobnicate", 42} };
sort_by_key(foobar.begin(), foobar.end(), [](const Foo& foo) {return foo.name; });
模板
按密钥进行无效排序(Iter from、Iter to、Func get密钥){
标准::排序(从、到、,
[获取_键](自动左、自动右){
返回get_键(lhs)
C++20附带了在需要时使用范围而不是迭代器对

除此之外,投影(与反转顺序的标志相结合)更简洁,因为作业是直接进行的,就像相同顺序中的所有子键一样,并且所有子键都按照其“自然”顺序排序。
比较器并没有针对这种情况进行无情的优化,它可以轻松地进行交易,以获得全面的最佳性能,并轻松地执行要求更高甚至完全奇怪的订单

Python只允许投影和可选的反转标志

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

除非发生这种情况,否则您可以通过投影和顺序关系轻松合成比较:

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()});
模板
结构使用投影{
[[no_unique_address]]Projection p=Projection();
[[no_unique_address]]比较器c=比较器();
模板
自动运算符()(T&…T)常量
noexcept(noexcept(c(p(std::forward(t))…)
->decltype(c(p(std::forward(t))…)
{返回c(p(std::forward(t))…);}
};
自动my_投影=[](自动和&x)->自动和&{return x.y;};
排序(v.begin(),v.end(),使用_投影{my_投影});
std::sort(v.begin(),v.end(),use_projection{my_projection,std::greater()});

对于C++17之前的版本,调整这个想法是留给读者的一个练习。

否。算法是使用迭代器基于范围的。但是你可以自己做一个版本,一个ARG…你可能想要C++ 20的范围。在此之前,它都是迭代器对。
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()});