std::p riority_queue::p op 迭代器失效

std::priority_queue::pop iterators invalidating

提问人:wowonline 提问时间:7/23/2023 更新时间:7/24/2023 访问量:46

问:

使用函数会使其他堆元素迭代器失效吗? 例如,我有带有元素的 minheap 和指向具有值的元素的迭代器。将 pop 应用于此堆后是否有效?priority_queue::pop(){1, 2, 3, 4}it2*it

C++ 标准堆

评论


答:

3赞 Jerry Coffin 7/23/2023 #1

简短的回答是否定的(至少在通常情况下 - 见下文)。

pop在优先级队列上等同于:

pop_heap(c.begin(), c.end(), comp);
c.pop_back();

...where 是对基础容器的引用。c

pop_heap它本身只将元素重新排列到基础集合中 - 交换容器中的第一个和最后一个元素,然后将第一个到最后一个元素放回堆中。

默认情况下,基础容器将是 ,在这种情况下,它使引用刚刚删除的元素的任何迭代器无效,并且可能使任何过去结束的迭代器无效。std::vectorpop_back

唯一可以合理用作 a 的底层容器的其他标准容器是 ,其工作方式几乎相同 - 将使该元素的迭代器无效,以及 one-past-the-end 迭代器。(注意:我并不是说有充分的理由使用 a 而不是 a ,只是你可以这样做,这不一定是一个大问题)。priority_queuestd::dequepop_backdequevector

如果你非常想,你可以设计一些你自己的容器,并实例化一个,在这种情况下,仍然会在底层容器上做一个,无论碰巧有什么效果。虽然我可以很容易地看到这类似于一个加号互斥锁(或类似的东西)以允许线程之间的共享,但我认为实例化一个容器的迭代器失效规则与 or .priority_queuepoppriority_queuepop_backvectorpriority_queuevectordeque

引用

  • [priqueue.members]/6

    void pop();

    效果:仿佛是:

        pop_heap(c.begin(), c.end(), comp);
        c.pop_back();
    
  • [deque.modifiers]/4

    效果:擦除 deque 的最后一个元素的擦除操作仅使过去结束迭代器以及所有迭代器和对擦除元素的引用无效。

  • [vector.修饰符]/3

    效果:使拭除点或之后的迭代器和参照失效。