我使用std::queue实现JobQueue类。(基本上这个类以FIFO方式处理每个作业)。 在一个场景中,我希望一次性清除队列(从队列中删除所有作业)。 我在std::queue类中没有看到任何可用的清除方法。

如何有效地实现JobQueue类的清除方法?

我有一个简单的解决方案弹出在一个循环,但我正在寻找更好的方法。

//Clears the job queue
void JobQueue ::clearJobs()
 {
  // I want to avoid pop in a loop
    while (!m_Queue.empty())
    {
        m_Queue.pop();
    }
}

当前回答

Author of the topic asked how to clear the queue "efficiently", so I assume he wants better complexity than linear O(queue size). Methods served by David Rodriguez, anon have the same complexity: according to STL reference, operator = has complexity O(queue size). IMHO it's because each element of queue is reserved separately and it isn't allocated in one big memory block, like in vector. So to clear all memory, we have to delete every element separately. So the straightest way to clear std::queue is one line:

while(!Q.empty()) Q.pop();

其他回答

使用unique_ptr也可以。 然后重置它以获得一个空队列并释放第一个队列的内存。 至于复杂性呢?我不确定,但我猜是O(1)

可能的代码:

typedef queue<int> quint;

unique_ptr<quint> p(new quint);

// ...

p.reset(new quint);  // the old queue has been destroyed and you start afresh with an empty queue

另一个选择是使用一个简单的hack来获取底层容器std::queue::c并调用clear。按照标准,该成员必须出现在std::queue中,但不幸的是,它受到了保护。这里的黑客是从这个答案中截取的。

#include <queue>

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);
}

template<typename T, typename C>
void clear(std::queue<T,C>& q)
{
    get_container(q).clear();
}

#include <iostream>
int main()
{
    std::queue<int> q;
    q.push(3);
    q.push(5);
    std::cout << q.size() << '\n';
    clear(q);
    std::cout << q.size() << '\n';
}

假设你的m_Queue包含整数:

std::queue<int>().swap(m_Queue)

否则,如果它包含例如指向Job对象的指针,则:

std::queue<Job*>().swap(m_Queue)

这样你就用你的m_Queue交换了一个空队列,这样m_Queue就变成了空队列。

在c++ 11中,你可以通过这样做来清除队列:

std::queue<int> queue;
// ...
queue = {};

清除标准容器的一个常用习语是交换容器的空版本:

void clear( std::queue<int> &q )
{
   std::queue<int> empty;
   std::swap( q, empty );
}

它也是清除某些容器内内存的唯一方法(std::vector)