C++\'s STL priority queue have a void pop() method, and a const ref top() method. Thus, if you want to move elements out of the queue, you have to do something like this:
std::priority_queue
is basically a thin layer on top of the heap algorithms. You can easily create your own priority queue with:
Using these building blocks, the implementation is trivial, and you can easily implement a moving pop operation. The following listing contains a minimal, working implementation:
template <typename Type, typename Compare = std::less<Type>>
class queue
{
private:
std::vector<Type> _elements;
Compare _compare;
public:
explicit queue(const Compare& compare = Compare())
: _compare{compare}
{ }
void push(Type element)
{
_elements.push_back(std::move(element));
std::push_heap(_elements.begin(), _elements.end(), _compare);
}
Type pop()
{
std::pop_heap(_elements.begin(), _elements.end(), _compare);
Type result = std::move(_elements.back());
_elements.pop_back();
return std::move(result);
}
};
This is indeed a flaw in std::priority_queue
. But you can easily extend it like this:
template <
class T,
class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type>>
class priority_queue : public std::priority_queue<T, Container, Compare> {
public:
T top_and_pop() {
std::pop_heap(c.begin(), c.end(), comp);
T value = std::move(c.back());
c.pop_back();
return value;
}
protected:
using std::priority_queue<T, Container, Compare>::c;
using std::priority_queue<T, Container, Compare>::comp;
};
(based on @nosid answer)