使用作用域限定的queue :: swap清空std :: queue是否违反任何规则?

Wee*_*are 6 c++ queue scope

我在许多情况下都在使用队列,队列可能增长到数百个。不幸的是,如果有必要的话,没有一种解决队列清空的方法。我想知道是否使用作用域队列进行交换,然后销毁作用域队列,是否破坏了任何内存分配/管理规则?

以下代码段是我建议的示例。如果长时间使用,似乎工作正常,不确定结果。

#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)

Nat*_*ica 5

您的代码很好。 swap将创建foo默认构造,std::queue并且在bar作用域末尾销毁该对象时,它将释放foo正在使用的内存。由于您不使用newdelete没有问题,因为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)


Lig*_*ica 2

这不仅是完全安全的,而且也是容器的移动构造函数通常的工作方式:通过与一个短暂的(或至少即将被销毁)的其他对象交换,然后让另一个对象消亡。然后,析构函数会尽快为您完成所有数据清理工作。(这里解决了缺少clear()成员函数的问题。)

我认为如果我需要一次性“清除”操作,并且我真的想使用队列(例如,像您所说的那样强制使用 FIFO),那么我会做同样的事情。

不过,如果您可以让旧容器超出范围并切换到新声明的容器上,那就更好了。