我需要维护大型对象(类型为Q
)的优先级队列T
。由于复制这些对象非常昂贵,因此我希望能够使用auto h = std::move(Q.top())
检索可写对象。但由于std::priority_queue<std::unique_ptr<T>>::top()
仅返回const引用,因此无法执行此操作。为什么? (有一个简单的解决方法吗?)
答案 0 :(得分:1)
您可以将大型对象作为unique_ptr<T>
存储在优先级队列中。需要注意的是queue.top()
返回一个const unique_ptr<T>&
,这意味着T
本身不是 const
。因此,您可以这样做:
T obj(std::move(*queue.top()));
queue.pop();
编辑:由于您的T
没有move构造函数,因此,我只说一点,然后使用std::shared_ptr<T>
:
std::priority_queue<std::shared_ptr<T>, ...> queue;
// fill queue
// No need for anything special.
std::shared_ptr<T> ptr = queue.top();
queue.pop();
答案 1 :(得分:0)
您可以将大对象包装到其他结构中,该结构将具有一个供自定义比较功能使用的字段,该成员不应受 move 操作的影响,例如,它应受某些普通数据的影响像mr={5px}
这样的类型:
int
在struct BigObject {
std::unique_ptr<int> data;
int forCmp;
};
struct Cmp {
bool operator()(const BigObject& lhs, const BigObject& rhs) {
return lhs.forCmp < rhs.forCmp;
}
};
队列内部顺序之后的不能被破坏。已移动的BigObject实例仍具有比较器使用的有效值move(queue.top())
。
然后从forCmp
继承,通过执行此操作,您将可以访问priority_queue
底层容器,并添加c
方法:
front
用途:
template<class T, class Cmp>
struct Wrapper : std::priority_queue<T,std::vector<T>,Cmp> {
T& front() {
return this->c.front();
}
};
答案 2 :(得分:0)
您可以继承priority_queue
并写成T pop()
来隐藏void pop()
template <typename T>
T fixed_priority_queue<T>::pop() {
std::pop_heap(c.begin(), c.end(), comp);
T value = std::move(c.back());
c.pop_back();
return value;
}