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

如何对存储Food对象shared_ptr的C++向量进行排序?

对std::vector<std::shared_ptr<Food>>排序的实现方案

嘿,我来帮你搞定这个排序问题!首先得明确:因为Food的成员都是私有属性,我们得先给Food类加几个公共的getter方法,这样才能在排序时访问到这些属性。先补全Food类的必要代码:

#include <string>

class Food {
private:
    std::string _description; // 食物描述,比如"all-purpose wheat flour"
    std::string _amount;      // 份量描述,比如"1 cup"
    int _amount_g;            // 份量克数,非负
    int _calories;            // 能量(千卡),你没写完,我先默认补这个成员啦
public:
    // 假设你已经有合适的构造函数,这里只加getter
    const std::string& getDescription() const { return _description; }
    int getAmountG() const { return _amount_g; }
    int getCalories() const { return _calories; }
};

接下来我们用C++标准库的std::sort算法(需要包含<algorithm>头文件),结合lambda表达式(最常用、最灵活的方式)来实现不同需求的排序:


1. 按食物描述的字典序排序

这是最基础的字符串排序,直接比较_description的字典序:

#include <algorithm>
#include <vector>
#include <memory>

std::vector<std::shared_ptr<Food>> foods; // 你的shared_ptr向量

// 按描述升序排列(A-Z)
std::sort(foods.begin(), foods.end(),
    [](const std::shared_ptr<Food>& a, const std::shared_ptr<Food>& b) {
        // 先处理空指针:把空指针放到向量末尾
        if (!a && !b) return false;
        if (!a) return false;
        if (!b) return true;
        return a->getDescription() < b->getDescription();
    });

如果要降序(Z-A),把<改成>就行。


2. 按食物重量(_amount_g)排序

按单份食物的克数从小到大/从大到小排序:

// 按重量升序(轻→重)
std::sort(foods.begin(), foods.end(),
    [](const std::shared_ptr<Food>& a, const std::shared_ptr<Food>& b) {
        if (!a && !b) return false;
        if (!a) return false;
        if (!b) return true;
        return a->getAmountG() < b->getAmountG();
    });

// 按重量降序(重→轻),只需要把比较符号反过来
std::sort(foods.begin(), foods.end(),
    [](const std::shared_ptr<Food>& a, const std::shared_ptr<Food>& b) {
        if (!a && !b) return false;
        if (!a) return false;
        if (!b) return true;
        return a->getAmountG() > b->getAmountG();
    });

3. 按能量(卡路里)排序

这里分两种场景:一种是按单份食物的总卡路里,另一种是更实用的**每100克卡路里(能量密度)**排序:

// 场景1:按单份总卡路里升序
std::sort(foods.begin(), foods.end(),
    [](const std::shared_ptr<Food>& a, const std::shared_ptr<Food>& b) {
        if (!a && !b) return false;
        if (!a) return false;
        if (!b) return true;
        return a->getCalories() < b->getCalories();
    });

// 场景2:按每100克卡路里升序(更合理,适合对比不同食物的能量密度)
std::sort(foods.begin(), foods.end(),
    [](const std::shared_ptr<Food>& a, const std::shared_ptr<Food>& b) {
        if (!a && !b) return false;
        if (!a) return false;
        if (!b) return true;
        // 处理重量为0的情况,避免除以0
        if (a->getAmountG() == 0) return false;
        if (b->getAmountG() == 0) return true;
        // 计算每100克的卡路里
        double calPer100gA = static_cast<double>(a->getCalories()) / a->getAmountG() * 100;
        double calPer100gB = static_cast<double>(b->getCalories()) / b->getAmountG() * 100;
        return calPer100gA < calPer100gB;
    });

4. 复用排序逻辑的进阶写法

如果某个排序规则要多次使用,可以把lambda改成命名函数或者函数对象:

方式1:命名函数

// 定义全局或命名空间内的比较函数
bool compareFoodByDescription(const std::shared_ptr<Food>& a, const std::shared_ptr<Food>& b) {
    if (!a && !b) return false;
    if (!a) return false;
    if (!b) return true;
    return a->getDescription() < b->getDescription();
}

// 调用排序
std::sort(foods.begin(), foods.end(), compareFoodByDescription);

方式2:函数对象(适用于带状态的比较逻辑)

struct CompareFoodByAmountG {
    bool isDescending; // 可以传入参数控制升序/降序
    CompareFoodByAmountG(bool desc = false) : isDescending(desc) {}

    bool operator()(const std::shared_ptr<Food>& a, const std::shared_ptr<Food>& b) const {
        if (!a && !b) return false;
        if (!a) return false;
        if (!b) return true;
        if (isDescending) {
            return a->getAmountG() > b->getAmountG();
        } else {
            return a->getAmountG() < b->getAmountG();
        }
    }
};

// 调用:升序排序
std::sort(foods.begin(), foods.end(), CompareFoodByAmountG());
// 调用:降序排序
std::sort(foods.begin(), foods.end(), CompareFoodByAmountG(true));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:32:43