如何使用用户定义的对象从priority_queue获取非const顶级元素?

pol*_*rto 12 c++ const priority-queue c++11

std :: priority_queue :: top返回一个常量值.但是,我想从优先级队列中删除顶部元素,并能够在其他地方修改它.

priority_queue<SomeClass, vector<SomeClass>, SomeClassCompare > pQueue;
...
SomeClass *toBeModified = &(pQueue.top());
pQueue.pop();
toBeModified->setMember(3); // I would like to do this
Run Code Online (Sandbox Code Playgroud)

有没有办法可以从优先级队列中获取顶级元素(并从队列中删除)并按照我的意愿修改它?

And*_*owl 16

标准容器和容器适配器具有值语义.将元素推入队列时,会创建一个副本.从队列中删除对象时,该对象将被销毁.

即使top()将返回对非的引用const,只要从队列中删除该元素,该引用就会变为悬空,并且取消引用它将导致未定义的行为.

这就是说,为了防止你(有意或无意地)弄乱它的内部顺序,std::priority_queue你会返回一个引用const- 这就是为什么关联容器的键如std::map和的std::set原因const.

相反,你可以做的是构造一个返回值的副本top(),修改该副本,删除原始副本,并将副本推送到队列中:

SomeClass obj = pQueue.top();
pQueue.pop();
obj.setMember(42);
pQueue.push(std::move(obj)); // You can move obj into the queue if you no more need it
Run Code Online (Sandbox Code Playgroud)

另一方面,如果需要引用语义,则必须将指针推入队列(可能是智能指针,具体取决于您的用例)并提供适当的自定义排序标准,该标准将根据对象的属性对这些指针进行排序他们指出.

在这种情况下,请注意不要在运行时修改这些属性,以使它们的顺序不同.这将被视为" 搞乱容器的内部排序 ",并将导致未定义的行为.

  • @Ethouris你错误地将整个声明标记为"完整BS".具有讽刺意味的是,这几乎与你攻击"废话"本身的原因相同. (2认同)