You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C++20 Ranges投影实现降序排序?

C++20范围排序:利用投影实现降序排序

现有如下Person类定义:

class Person
{
    friend std::ostream &operator<<(std::ostream &out, const Person &operand);

public:
    Person(std::string name, std::string address, int age, int height, int weight)
        : m_name(name), m_address(address), m_age(age), m_height(height), m_weight(weight)
    {
    }

public:
    std::string m_name;
    std::string m_address;
    int m_age;
    int m_height;
    int m_weight;
};

std::ostream &operator<<(std::ostream &out, const Person &operand)
{
    out << "Person [" << operand.m_name << ", " << operand.m_age << "]";
    return out;
}

使用C++20的投影功能,可通过以下代码实现按年龄升序排序:

std::ranges::sort(persons, {}, &Person::m_age);

尝试以下两种写法实现降序排序时均出现编译错误:

// 错误:对成员指针做算术运算非法
std::ranges::sort(persons, {}, -1 * &Person::m_age);
// 错误:std::ranges::reverse没有接受投影参数的重载
std::ranges::reverse(persons, {}, &Person::m_age);

编译命令:

g++ "-static" -o main.exe .\*.cpp -std=c++20

正确的降序实现方式

方法1:使用反向比较器配合投影

直接传入std::ranges::greater{}作为比较器,结合投影参数即可实现降序:

std::ranges::sort(persons, std::ranges::greater{}, &Person::m_age);

std::ranges::greater{}会将投影后的值按从大到小的顺序比较,从而让原序列按年龄降序排列。

方法2:自定义lambda比较器

如果需要更灵活的逻辑,可以自定义lambda,直接比较年龄的大小:

std::ranges::sort(persons, [](const auto& a, const auto& b) {
    return a.m_age > b.m_age;
});

这种写法也能实现降序,本质是直接比较目标属性,和投影写法的效果一致,但投影写法更简洁。

方法3:先升序再反转序列

先按升序排序,再调用std::ranges::reverse反转整个序列:

std::ranges::sort(persons, {}, &Person::m_age);
std::ranges::reverse(persons);

这种方式可行,但效率略低于直接使用反向比较器,因为需要额外的反转操作。

错误写法原因说明

  • 第一种错误写法试图对成员指针&Person::m_age做算术运算,这在C++中是非法的,成员指针不支持此类数值运算。
  • 第二种错误写法误用了std::ranges::reverse,该函数仅负责反转整个序列的元素顺序,没有接受投影参数的重载,无法根据某个属性的顺序调整序列。

内容的提问来源于stack exchange,提问作者VivekDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:47:17