C++向STL函数传参:priority_queue比较器传unordered_map报错排查
解决priority_queue比较器参数传递的模板错误
哦,这个错误我太熟悉了!你现在踩的坑是priority_queue模板参数的基本规则——第三个模板参数要求传入的是一个类型,但你写的compare(freq)是一个已经构造好的对象实例,这直接违反了模板参数的要求,编译器当然会报错「Template argument for template type parameter must be a type」啦。
错误原因拆解
std::priority_queue的模板定义核心逻辑是这样的:
template<class T, class Container = vector<T>, class Compare = less<T>> class priority_queue;
第三个参数Compare必须是一个类型(比如less<int>、你自定义的compare结构体类型),而不是这个类型的对象。你之前直接把compare(freq)(对象实例)塞到模板参数位置,完全不符合模板的语法要求。
正确的写法调整
我们需要把「指定比较器类型」和「传入比较器实例」分开两步来做:
第一步:修正你的compare结构体
首先给比较器的operator()加上const(因为priority_queue会以const方式调用这个方法),同时处理好map的生命周期(可选引用或拷贝,根据你的场景选择):
struct compare { // 方式1:拷贝map,不用担心生命周期问题(推荐新手用) compare(const std::unordered_map<int, int>& freq1) : freq(freq1) {} // 方式2:用const引用,前提是原map的生命周期比priority_queue长 // compare(const std::unordered_map<int, int>& freq1) : freq(freq1) {} // const std::unordered_map<int, int>& freq; // 必须加const,否则priority_queue调用时会报错 bool operator()(const int& el1, const int& el2) const { // 用at()代替[],避免key不存在时自动插入默认值 return freq.at(el1) < freq.at(el2); } private: std::unordered_map<int, int> freq; // 方式1的成员变量 };
第二步:正确声明并构造priority_queue
现在模板参数传compare类型,然后在构造pq的时候,把比较器的实例作为构造函数参数传进去:
// 假设你已经有一个std::unordered_map<int, int> freq; std::priority_queue<int, std::vector<int>, compare> pq(compare(freq)); // 或者用C++11+的统一初始化写法,更简洁: std::priority_queue<int, std::vector<int>, compare> pq{compare(freq)};
额外注意点
- 如果选择用引用持有map,一定要保证原
freq对象的生命周期长于priority_queue的生命周期,否则会出现悬空引用,导致未定义行为。 - 用
freq.at(el1)而不是freq[el1],因为[]运算符在key不存在时会自动插入一个值为0的元素,这大概率不是你想要的逻辑,at()会直接抛出异常提醒你key不存在的问题。
内容的提问来源于stack exchange,提问作者nikgpuec
相关产品推荐
相关产品推荐

