我有点困惑。我所学到的或者被告知的是,如果调用erase,向量的迭代器就会失效。但是为什么下面的代码是有效的。它使用g++编译,并在Linux上运行。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vector<int>::iterator it = vec.begin();
++it;
vector<int>::iterator it2;
it2 = vec.erase(it);
cout << "it: " << *it << endl;
cout << "it2: " << *it2 << endl;
}感谢您的反馈!
发布于 2012-02-16 19:15:12
来自http://www.cplusplus.com/reference/stl/vector/erase/ (不是世界上最好的C++参考):
这将使所有迭代器和对position (或first)及其后续元素的引用无效。
所以it是无效的;使用它会导致未定义的行为。事实上,你碰巧得到了你期望的东西,这纯粹是运气不好。
发布于 2012-02-16 19:15:21
你所做的是未定义的行为,它的“工作”完全是偶然的。你不能也不能依赖它,因为它可以做任何事情。它的行为没有定义。
发布于 2012-02-16 22:36:38
作为实现细节,vector<int>::iterator可以很容易地被int*。我认为在g++中,int*是一个非常薄的包装器。如果是这种情况,那么擦除三元素向量的中间元素意味着it的指针数据成员指向与被删除的元素相同的地址,当然,它将包含先前紧随其后的值,并且it2也有效地引用了该值。
该标准并不保证it仍然会引用任何内容,这就是为什么您不能依赖于您在这里观察到的行为。但它解释了你所看到的。当您取消对it的引用时,一个实现很大程度上必须走自己的路,才能使任何其他事情发生。但是编译器确实每天都在走自己的路:例如,调试库的版本,以及一些优化技术依赖于您的代码正确的假设。
https://stackoverflow.com/questions/9310263
复制相似问题