pop_back()是否真的使std :: vector上的*all*迭代器无效?

ace*_*mtp 5 c++ stl

std::vector<int> ints;

// ... fill ints with random values

for(std::vector<int>::iterator it = ints.begin(); it != ints.end(); )
{
    if(*it < 10)
    {
        *it = ints.back();
        ints.pop_back();
        continue;
    }
    it++;
}
Run Code Online (Sandbox Code Playgroud)

此代码无效pop_back(),因为调用时it无效.但是我找不到任何关于迭代器失效的文档std::vector::pop_back().

你有相关的链接吗?

小智 12

调用pop_back()移除向量中的最后一个元素,因此该元素的迭代器无效.该pop_back()调用并没有最后的元素之前迭代器失效的项目,只有重新分配将这样做.来自Josuttis的"C++标准库参考":

插入或删除元素会使引用,引用和迭代器无效,这些引用,引用和迭代器引用以下元素.如果插入导致重新分配,则会使所有引用,迭代器和指针无效.

  • cplusplus.com是一个糟糕的网站; 永远不要用它作为参考. (5认同)
  • @BruceConnor怎么样[http://www.cppreference.com](http://www.cppreference.com)? (2认同)

小智 12

以下是您的答案,直接来自The Holy Standard:

23.2.4.2载体满足容器和可逆容器的所有要求(在23.1中的两个表中给出)和序列,包括大多数可选的序列要求(23.1.1).
23.1.1.12表68 expressiona.pop_back()返回typevoid操作语义a.erase( - a.end()) containervector,list,deque

请注意,a.pop_back等同于a.erase( - a.end()).看看矢量的擦除细节:

23.2.4.3.3 - 迭代器擦除(迭代器位置) - 效果 - 在擦除点之后使所有迭代器和引用无效

因此,一旦调用pop_back,任何先前最终元素(现在不再存在)的迭代器都将失效.

查看您的代码,问题是当您删除最后一个元素并且列表变为空时,您仍然会增加它并离开列表的末尾.


Pie*_*ter 5

(我使用 C++0x 工作草案中使用的编号方案,可在此处获得

第 732 页的表 94 说 pop_back(如果它存在于序列容器中)具有以下效果:

{ iterator tmp = a.end(); 
--tmp; 
a.erase(tmp); } 
Run Code Online (Sandbox Code Playgroud)

23.1.1,第 12 点指出:

除非另有规定(显式或根据其他函数定义函数),调用容器成员函数或将容器作为参数传递给库函数不应使迭代器无效或更改其值,该容器内的对象。

访问 end() 作为应用前缀 - 没有这样的效果,但是擦除():

23.2.6.4(关于 vector.erase() 点 4):

效果:在擦除点或之后使迭代器和引用无效。

所以总而言之:根据标准,pop_back() 只会使最后一个元素的迭代器无效。