如何有效地清除std ::队列?

我正在使用std ::队列来实现JobQueue类。 (基本上这个类以FIFO的方式处理每个工作)。 在一种情况下,我想要一次性清除队列(从队列中删除所有作业)。 我在std :: queue类中看不到任何清晰的方法。

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

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

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

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

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

这也是实际清除内存容器(std :: vector)的唯一方法

是的 – 有一个队列类,恕我直言,misfeature。 这就是我所做的:

 #include <queue> using namespace std;; int main() { queue <int> q1; // stuff q1 = queue<int>(); } 

“David Rodriguez”,“anon”这个主题的作者询问如何“有效地”清除队列,所以我假设他希望比线性O(队列的大小)更好的复杂性。 您提供的方法具有相同的复杂度:根据stl引用,operator =具有复杂度O(队列的大小)。 恕我直言,这是因为队列中的每个元素都是单独保留的,并没有像在向量中一样分配在一个大的内存块中。 所以要清除所有内存,我们必须分别删除每个元素。 所以清除stl::queue最直接的方法就是一行:

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

显然,有两个最明显的方法来清除std::queue :交换与空对象和分配给空对象。

我会build议使用分配,因为它只是更快,更可读,明确。

我使用以下简单代码测量了性能,发现在C ++ 03版本中交换工作速度比分配给空对象慢70-80%。 在C ++ 11中,性能没有什么不同。 无论如何,我会去做任务。

 #include <algorithm> #include <ctime> #include <iostream> #include <queue> #include <vector> int main() { std::cout << "Started" << std::endl; std::queue<int> q; for (int i = 0; i < 10000; ++i) { q.push(i); } std::vector<std::queue<int> > queues(10000, q); const std::clock_t begin = std::clock(); for (std::vector<int>::size_type i = 0; i < queues.size(); ++i) { // OK in all versions queues[i] = std::queue<int>(); // OK since C++11 // std::queue<int>().swap(queues[i]); // OK before C++11 but slow // std::queue<int> empty; // std::swap(empty, queues[i]); } const double elapsed = double(clock() - begin) / CLOCKS_PER_SEC; std::cout << elapsed << std::endl; return 0; } 

您可以创build一个从队列inheritance的类,并直接清除底层容器。 这非常有效。

 template<class T> class queue_clearable : public std::queue<T> { public: void clear() { c.clear(); } }; 

也许你的一个实现也允许你的Queue对象(这里是JobQueue )inheritancestd::queue<Job>而不是将队列作为成员variables。 这样你就可以在你的成员函数中直接访问c.clear()

在C ++ 11中,您可以通过执行以下操作清除队列:

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

我宁愿不依靠swap()或将队列设置为新创build的队列对象,因为队列元素没有正确销毁。 调用pop()调用相应元素对象的析构函数。 这可能不是在<int>队列中的问题,但可能会对包含对象的队列产生副作用。

因此, while(!queue.empty()) queue.pop(); 不幸的是,如果你想防止可能的副作用,至less对于包含对象的队列是最有效的解决scheme。

使用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