我可以通过清除其底层容器来清除priority_queue
May I clear a priority_queue by clearing its underlying container?
以下代码继承了std::p riority_queue,并提供了调用内部std::vector
clear()
的clear()
#include<iostream>
#include<queue>
using namespace std;
template<class type>
struct mypq :public priority_queue<type> {
void clear(){
this->c.clear();
}
};
mypq<int>pq;
int main() {
for(int i=0;i<10;++i)
pq.push(i);
pq.clear();
for(int j=-5;j<0;++j)
pq.push(j);
while (!pq.empty()){
cerr<<pq.top()<<endl;
pq.pop();
}
}
当我用 g++、MSVC++ 和 clang 测试它时,它产生了预期的输出:
-1
-2
-3
-4
-5
但我还没有看到任何保证,即清除内部向量与在priority_queue不为空时调用pop()
相同。尽管我知道清除它的其他方法,例如交换或使用空priority_queue分配它,但我认为如果这段代码可以正常工作,它会更有效,因为矢量中分配的内存是可重用的。所以我想知道这段代码是可移植的还是并不总是有效的?
但是我还没有看到任何保证,即清除内部向量与在priority_queue不为空时调用
pop()
相同。
因为那不是一回事。std::priority_queue
是一种专门设计的容器适配器,通过严格的弱排序来保持物品的有序。如果未指定队列将具有的容器类型(在示例中未指定),则默认类型为 std::vector
。
因此,在非空优先级队列上调用 pop()
将具有从队列中删除顶部元素的效果,而对基础容器调用 clear()
将从队列中删除所有元素,而不仅仅是最顶层的元素。
尽管我知道清除它的其他方法,例如交换或使用空priority_queue分配它,但我认为如果这段代码可以正常工作,它会更有效,因为矢量中分配的内存是可重用的。所以我想知道这段代码是可移植的还是并不总是有效的?
根据参考文献,底层c
成员对象是受保护的,因此应该保证跨编译器访问您的方式,也就是说,调用this->c.clear();
应该是可移植的(有趣的是,它适用于旧版本的OpenBSD的g++ 4.2.1
)。
就效率而言,这在某种程度上取决于。做一些类似this->c.clear();
与 q = priority_queue <int>();
在内存使用或复杂性方面可能没有太大区别,尽管您必须在不同的平台上对其进行测试才能验证。但是,做一些类似 this->c.clear();
vs. while(!q.empty()) { q.pop(); }
,会更有效率。
在内存效率方面,优先级队列的pop
函数调用底层容器pop_back
函数,pop_back
和clear
都不会影响底层向量的capacity
,因此实际上没有任何"节省"以这种方式; 尽管有了这个,如果您有特定需要,您可以调整矢量的大小以增加/减少容量。
请记住,优先级队列pop
函数调用函数pop_back
底层容器,在空容器上调用pop_back
是未定义的行为。
希望能有所帮助。
一个非常好的问题。虽然我似乎找不到任何严格的保证它是一种正确的方法,但有一些理由认为它是。
例如,考虑operator=
的文档:
复制赋值运算符。将内容替换为 其他内容。有效地调用
c = other.c;
。(隐式 声明)
由于另一个队列的大小可能不同,这实质上意味着没有依赖于大小的内部状态。此外,它还意味着分配一个空队列实质上是用一个空队列替换容器,而不做任何其他事情。
考虑到这一点,以及优先级队列的合理实现几乎不需要维护任何状态的事实,除了队列的大小,我相信可以安全地假设清除底层容器是清空队列的有效方法。
- 清除前检查矢量
- ifstream文件在从行中读取时被清除
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- 如何清除/清空已打开的文件C++
- 如何在 c++ 中清除矢量容量?
- 可以清除递归函数中的变量吗?
- 在清除 istream 之前,我不应该需要取消获取它吗?
- 结构成员在访问时被清除
- 清除输入缓冲区后未提取字符串流
- SDL_ttf清除我之前和将来的所有渲染
- 如何使用内存集清除字符数组
- 有没有办法在c ++中清除空数组,请检查下面的代码以获取说明
- QTreeWidgetItem 设置不可选择将清除选择
- libQGLViewer 如何在没有清除缓冲区的情况下绘制
- 清除具有已删除赋值运算符的成员的类实例
- 清除结构向量时会发生什么?
- 显式清除 std::move 之后的源资源
- C++ - 重置字符串流不会重置获取位置或清除标志吗?
- std::cin 在读取 EOF 并清除后不再读取
- 清除在 main() 中分配的堆栈内存?