如何将元素移出STL优先级队列

Ant*_*t6n 9 c++ move-semantics c++11 c++03

C++的STL优先级队列有一个void pop()方法和一个const ref top()方法.因此,如果要将元素移出队列,则必须执行以下操作:

T moved = std::move(const_cast<T&>(myQueue.top())));
myQeue.pop();
Run Code Online (Sandbox Code Playgroud)

这有效地将顶部强制转换为常量,以便可以移动(而不是复制).我不喜欢这段代码,因为强制移动可能会使优先级队列的不变量无效,这不应该因为pop而烦恼,但事情可能会出错.

有没有更好的方法来完成弹出/移动?为什么没有T && top_and_pop()函数?

nos*_*sid 10

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

  • +1我也应该检查/`static_assert`为`is_nothrow_move_constructible`(即使在最小的实现中),否则你可能会丢失`pop`中的元素. (2认同)
  • `return std :: move(result)`中的`std :: move`是多余的. (2认同)