如何创建并使用带自定义比较器的优先队列映射?
带自定义参数比较器的优先队列存入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
相关产品推荐
相关产品推荐

