Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move elements out of STL priority queue

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:

T moved = std::move(const_cast<T&>(myQueue.top())));
myQeue.pop();

This effectively casts the top to not a constant, so that it can be moved (rather than copied). I don't like this code, because the forced move may invalidate the invariants of the priority queue, which should not matter because of the pop, but things could go wrong.

Is there a better way to accomplish the pop/move? Why is there no T&& top_and_pop() function?

like image 835
Ant6n Avatar asked Feb 26 '14 16:02

Ant6n


People also ask

How do I remove a specific item from a priority queue?

The remove() method of PriorityQueue class of java. util package is used to remove a particular element from a PriorityQueue.

Is priority queue in STL?

In C++, the STL priority_queue provides the functionality of a priority queue data structure. A priority queue is a special type of queue in which each element is associated with a priority value and elements are served based on their priority.

How are elements stored in priority queue?

The elements of the priority queue are ordered according to the natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used. In the below priority queue, an element with a maximum ASCII value will have the highest priority.


1 Answers

std::priority_queue is basically a thin layer on top of the heap algorithms. You can easily create your own priority queue with:

  • std::vector
  • std::push_heap
  • std::pop_heap

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);
    }
};
like image 147
nosid Avatar answered Oct 02 '22 10:10

nosid