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

如何清空使用自定义比较器的std::priority_queue?

如何清空使用自定义比较器的std::priority_queue?

我根据std::priority_queue的官方文档,编写了带自定义比较器的队列代码,可正常运行:

#include <functional>
#include <queue>
#include <vector>
#include <iostream>
#include <utility>

auto queue_cmp = [](std::pair<int, double> const& lhs,
                    std::pair<int, double> const& rhs) {
    return lhs.second > rhs.second; // 自定义排序规则
};
typedef std::priority_queue<std::pair<int, double>,
                            std::vector<std::pair<int, double>>,
                            decltype(queue_cmp)> custom_queue;

template<typename T>
void print_queue(T q) { // 传值以使用副本打印
    int s = 0;
    while(!q.empty()) {
        std::pair<int, double> elem = q.top();
        std::cout << s << ": " << elem.first << ", " << elem.second << std::endl;
        q.pop();
        s++;
    }
    std::cout << '\n';
}

int main() {
    custom_queue q(queue_cmp);
    for (int n = 10; n < 20; n++) {
        double val = static_cast <double>(rand())/(static_cast<double>(RAND_MAX));
        q.push(std::pair<int, double>(n, val));
    }
    print_queue(q);
    // q = custom_queue(queue_cmp); // 取消注释后编译报错
}

编译执行结果:

>> g++ -o test test.cpp 

>> ./test 
0: 15, 0.197551
1: 18, 0.277775
2: 16, 0.335223
3: 11, 0.394383
4: 19, 0.55397
5: 17, 0.76823
6: 12, 0.783099
7: 13, 0.79844
8: 10, 0.840188
9: 14, 0.911647

当我取消注释最后一行尝试重置队列时,出现编译错误,原因是lambda闭包类型的拷贝赋值运算符被删除,导致std::priority_queue的移动赋值运算符无法生成:

>> g++ -o test test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:34:31: error: use of deleted function ‘std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >& std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >::operator=(std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >&&)’
   34 |     q = custom_queue(queue_cmp);
      |                               ^
In file included from /usr/include/c++/12/queue:64,
                 from test.cpp:2:
/usr/include/c++/12/bits/stl_queue.h:498:11: note: ‘std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >& std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >::operator=(std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >&&)’ is implicitly deleted because the default definition would be ill-formed:
  498 |     class priority_queue
      |           ^~~~~~~~~~~~~~
/usr/include/c++/12/bits/stl_queue.h:498:11: error: use of deleted function ‘<lambda(const std::pair<int, double>&, const std::pair<int, double>&)>&<lambda(const std::pair<int, double>&, const std::pair<int, double>&)>::operator=(const<lambda(const std::pair<int, double>&, const std::pair<int, double>&)>&)’
test.cpp:7:19: note: a lambda closure type has a deleted copy assignment operator
    7 | auto queue_cmp = [](std::pair<int, double> const& lhs,
      |                   ^

我尝试将lambda换成普通函数比较器,问题依然存在:

bool queue_cmp(std::pair<int, double> const& lhs,
               std::pair<int, double> const& rhs) {
    return lhs.second > rhs.second; // 自定义排序规则
};

请问这种情况下如何重置队列q?


解决方案

方法1:循环调用pop()清空

最直接的方式,逐个弹出队列元素直到为空:

while (!q.empty()) {
    q.pop();
}

优点是无需修改原有代码结构,缺点是当队列元素数量极大时,效率略低于直接替换底层容器。

方法2:使用swap()交换空队列

利用std::priority_queue的swap()成员函数,和一个临时空队列交换内部状态。该操作不会触发赋值运算符,因此可以避开lambda的拷贝赋值问题:

q.swap(custom_queue(queue_cmp));

swap()仅交换队列的底层容器和比较器的内部引用,效率极高。

方法3:替换为可拷贝的比较器类型

将lambda或普通函数替换为结构体类型的比较器,这类类型默认支持拷贝和赋值,能让priority_queue的赋值运算符正常工作:

struct QueueCmp {
    bool operator()(const std::pair<int, double>& lhs, const std::pair<int, double>& rhs) const {
        return lhs.second > rhs.second;
    }
};

// 重新定义队列类型
typedef std::priority_queue<std::pair<int, double>,
                            std::vector<std::pair<int, double>>,
                            QueueCmp> custom_queue;

此时直接通过赋值空队列即可清空:

q = custom_queue();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:05:21