C ++的STL优先级队列有一个void pop()方法和一个const ref top()方法。因此,如果要将元素移出队列,则必须执行以下操作:
T moved = std::move(const_cast<T&>(myQueue.top())));
myQeue.pop();
这有效地将顶部强制转换为常量,以便可以移动(而不是复制)。我不喜欢这段代码,因为强制移动可能会使优先级队列的不变量无效,应该因为弹出而无关紧要,但可能出错。
有没有更好的方法来完成弹出/移动? 为什么没有T&amp;&amp; top_and_pop()函数?
答案 0 :(得分:9)
std::priority_queue
基本上是堆算法之上的薄层。您可以使用以下命令轻松创建自己的优先级队列
使用这些构建块,实现非常简单,您可以轻松实现移动弹出操作。以下清单包含一个最小的工作实现:
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);
}
};
答案 1 :(得分:0)
这确实是std::priority_queue
中的缺陷。但是您可以像这样轻松扩展它:
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;
};
(基于@nosid答案)