我使用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();
    }
}

当前回答

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

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

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

其他回答

您可以创建一个继承自队列的类,并直接清除底层容器。这是非常有效的。

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

也许你的a实现也允许你的Queue对象(这里是JobQueue)继承std:: Queue <Job>,而不是将Queue作为成员变量。这样就可以在成员函数中直接访问c.clear()。

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

假设你的m_Queue包含整数:

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

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

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

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

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

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

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

显然,有两种最明显的方法来清除std::queue:交换空对象和赋值给空对象。

我建议使用赋值,因为它更快、更易读、更明确。

我使用以下简单的代码测量了性能,我发现在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;
}