首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从优先级队列中获取unique_ptr

从优先级队列中获取unique_ptr
EN

Stack Overflow用户
提问于 2013-05-21 10:02:00
回答 2查看 4.4K关注 0票数 10

我在priority_queue中维护一组unique_ptr实例。在某个时刻,我想要获取第一个元素并将其从队列中删除。但是,这总是会产生编译器错误。请参阅下面的示例代码。

代码语言:javascript
复制
int main ()
{
  std::priority_queue<std::unique_ptr<int>> queue;
  queue.push(std::unique_ptr<int>(new int(42)));

  std::unique_ptr<int> myInt = std::move(queue.top());
  return 1;
}

这会产生以下编译器错误(gcc 4.8.0):

代码语言:javascript
复制
uptrtest.cpp: In function ‘int main()’: uptrtest.cpp:6:53: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’    std::unique_ptr<int> myInt = std::move(queue.top());
                                                     ^ In file included from /usr/include/c++/4.8/memory:81:0,
                 from uptrtest.cpp:1: /usr/include/c++/4.8/bits/unique_ptr.h:273:7: error: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^

像在this question中一样,将代码更改为使用queue可以解决这个问题,并且代码可以很好地编译。

有没有办法将unique_ptr%s保存在priority_queue中,或者我错过了什么?

EN

回答 2

Stack Overflow用户

发布于 2019-11-25 12:31:31

这是另一个丑陋的变通方法。就我个人而言,我更喜欢它而不是其他建议的丑陋的变通方法。根据您的情况,您可能需要使用此工具。将原始指针存储在优先级队列中。每次弹出时,确保将其放在唯一的指针中。还有一个析构函数来清理剩余的东西。

这是一个未经测试的代码。

代码语言:javascript
复制
class Queue_with_extra_steps {
public:
  void push( std::unique_ptr<int>&& value ) {
    queue.push( value.release() );
  }
  std::unique_ptr<int> pop() {
    if( queue.empty() ) {
      return nullptr;
    }
    std::unique_ptr<int> ans( queue.top() );
    queue.pop();
    return ans;
  }
  ~Queue_with_extra_steps() {
    while( !queue.empty() ) {
      this->pop();
    }
  }
  // Add other functions if need be.
private:
  std::priority_queue<int*> queue;
};
票数 0
EN

Stack Overflow用户

发布于 2022-01-20 12:59:19

一种不那么难看的解决方法是使用可变的unique_ptr创建包装器。您还可以分离“优先级数据”,以防止它破坏堆。

代码语言:javascript
复制
#include <iostream>
#include <queue>
#include <memory>
using namespace std;

template<typename T>
struct unique_ptr_storage{
    unique_ptr_storage(uint32_t _priority,std::unique_ptr<T> &&_ptr)
    : priority(_priority)
    , ptr(std::move(_ptr)){}
    
    mutable std::unique_ptr<T> ptr;
    std::unique_ptr<T> release()const{
        return std::move(ptr);
    }
    uint32_t priority;
    bool operator<(const unique_ptr_storage<T> &other)const{
        return priority<other.priority;
    }
};

int main() {
    std::priority_queue<unique_ptr_storage<int>> q;
    
    q.emplace(1,std::make_unique<int>(10));
    q.emplace(3,std::make_unique<int>(30));
    q.emplace(2,std::make_unique<int>(20));
    
    while(!q.empty()){
        std::unique_ptr<int> p=q.top().release();
        q.pop();
        std::cout<<*p<<std::endl;
    }
    return 0;
}

输出:

代码语言:javascript
复制
30
20
10
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16661038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档