我在许多情况下都在使用队列,队列可能增长到数百个。不幸的是,如果有必要的话,没有一种解决队列清空的方法。我想知道是否使用作用域队列进行交换,然后销毁作用域队列,是否破坏了任何内存分配/管理规则?
以下代码段是我建议的示例。如果长时间使用,似乎工作正常,不确定结果。
#include <cstdlib>
#include <iostream>
#include <queue>
int
main()
{
std::queue<int> foo;
foo.push(10);
foo.push(20);
foo.push(30);
std::cout << "size of before foo: " << foo.size() << '\n';
{
std::queue<int> bar;
swap(foo, bar);
}
std::cout << "size of after foo: " << foo.size() << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您的代码很好。 swap将创建foo默认构造,std::queue并且在bar作用域末尾销毁该对象时,它将释放foo正在使用的内存。由于您不使用new或delete没有问题,因为std::queue“做正确的事”(RAII类型是一件很棒的事)
实际上,您已经完成了
std::queue<int>{std::move(foo)}; // move foo into a temporary that is immediately destroyed to release the storage
Run Code Online (Sandbox Code Playgroud)
但是您的方法可以为您提供更强大的保证foo。您的方法foo处于默认的构造状态,而上述方法则使其处于有效但未指定的状态。
另一个选择是使用提供的解决方案之一。是否可以访问STL容器适配器的基础容器?从中获取基础容器foo并对其进行调用清除。看起来像
#include <cstdlib>
#include <iostream>
#include <queue>
// function from /sf/answers/2052768091/ by jxh: /sf/users/22053671/
template <class ADAPTER>
typename ADAPTER::container_type & get_container (ADAPTER &a)
{
struct hack : ADAPTER {
static typename ADAPTER::container_type & get (ADAPTER &a) {
return a.*&hack::c;
}
};
return hack::get(a);
}
int main()
{
std::queue<int> foo;
foo.push(10);
foo.push(20);
foo.push(30);
std::cout << "size of before foo: " << foo.size() << '\n';
get_container(foo).clear();
std::cout << "size of after foo: " << foo.size() << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这不仅是完全安全的,而且也是容器的移动构造函数通常的工作方式:通过与一个短暂的(或至少即将被销毁)的其他对象交换,然后让另一个对象消亡。然后,析构函数会尽快为您完成所有数据清理工作。(这里解决了缺少clear()成员函数的问题。)
我认为如果我需要一次性“清除”操作,并且我真的想使用队列(例如,像您所说的那样强制使用 FIFO),那么我会做同样的事情。
不过,如果您可以让旧容器超出范围并切换到新声明的容器上,那就更好了。
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |