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

当前回答

是的-有点队列类的错误特征,恕我直言。这就是我所做的:

#include <queue>
using namespace std;;

int main() {
    queue <int> q1;
    // stuff
    q1 = queue<int>();  
}

其他回答

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

std::queue<int> queue;
// ...
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';
}

我这样做(使用c++ 14):

std::queue<int> myqueue;
myqueue = decltype(myqueue){};

如果您有一个不平凡的队列类型,并且不想为其构建别名/typedef,则这种方法非常有用。不过,我总是确保就这种用法留下评论,向不知情的/维护程序员解释这并不疯狂,并代替了实际的clear()方法。

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

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