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

如何创建并使用带自定义比较器的优先队列映射?

带自定义参数比较器的优先队列存入map的问题解决

问题背景

想要构建订单积压队列,用map<string, priority_queue>存储不同标的的订单:

  • 键:标的字符串(symbol)
  • 值:优先队列,通过自定义比较器区分买单/卖单的优先级逻辑

自定义比较器代码:

struct Compare{
    bool buySide;
    Compare(bool side) : buySide(side) {}
    bool operator()(pair<int, float> order1, pair<int, float> order2) {
        if (buySide) {
            return order1.second < order2.second;
        }
        return order1.second > order2.second;
    };
};

尝试创建映射及使用时:

typedef priority_queue<pair<int, float>, vector<pair<int, float>>, Compare> priorityQueue;
map<string, priorityQueue> marketBuys;

// 初始化并插入订单的代码
if (marketBuys.find(order.symbol) == marketBuys.end()) {
    marketBuys[order.symbol] = priorityQueue(Compare(true));
}
marketBuys[order.symbol].push(make_pair(order.orderId, order.price));

遇到编译错误:

error: no matching function for call to ‘std::priority_queue<std::pair<int, float>, std::vector<std::pair<int, float> >, Compare>::priority_queue()’

单独创建优先队列可以正常运行,但无法放入map中,尝试临时变量赋值也失败。

错误原因

当调用marketBuys[order.symbol]时,如果对应键不存在,map会尝试默认构造一个priorityQueue对象。但你的priorityQueue没有默认构造函数:

  • Compare结构体没有默认构造函数(它的构造必须传入bool参数)
  • std::priority_queue的默认构造要求比较器类型支持默认构造,因此编译器找不到匹配的构造函数,抛出错误。

解决方案

方案1:使用emplace直接在map中构造(C++11及以上)

跳过默认构造步骤,直接通过emplace在map的指定键位置构造带目标比较器的优先队列:

typedef priority_queue<pair<int, float>, vector<pair<int, float>>, Compare> priorityQueue;
map<string, priorityQueue> marketBuys;

auto it = marketBuys.find(order.symbol);
if (it == marketBuys.end()) {
    // 构造优先队列并插入map,返回迭代器
    it = marketBuys.emplace(order.symbol, priorityQueue(Compare(true))).first;
}
// 向队列插入订单
it->second.push(make_pair(order.orderId, order.price));

方案2:使用try_emplace简化代码(C++17及以上)

try_emplace会自动检查键是否存在:不存在则直接构造对应值,存在则返回已有值的迭代器,无需额外的find判断:

typedef priority_queue<pair<int, float>, vector<pair<int, float>>, Compare> priorityQueue;
map<string, priorityQueue> marketBuys;

// 一行完成检查、构造(若需要)、获取队列引用
auto& targetQueue = marketBuys.try_emplace(order.symbol, Compare(true)).first->second;
targetQueue.push(make_pair(order.orderId, order.price));

这里try_emplace的第二个参数直接传入Compare(true),会被用来构造priorityQueue对象。

方案3:修改比较器支持默认构造(可选)

如果业务允许,可以给Compare添加默认构造函数,让priorityQueue支持默认构造,这样原代码的operator[]就能正常使用:

struct Compare{
    bool buySide;
    // 添加默认构造,默认设为买单逻辑(可按需调整)
    Compare() : buySide(true) {}
    Compare(bool side) : buySide(side) {}
    bool operator()(pair<int, float> order1, pair<int, float> order2) {
        if (buySide) {
            return order1.second < order2.second;
        }
        return order1.second > order2.second;
    };
};

⚠️ 注意:使用这个方案时,若不小心通过operator[]访问不存在的键,会创建一个带默认比较器的队列,可能不符合业务预期,需谨慎使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:55:05