我有点困惑。我学到或被告知的是,如果调用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;
}
感谢您的任何反馈!
答案 0 :(得分:2)
来自http://www.cplusplus.com/reference/stl/vector/erase/(不是世界上最好的C ++参考):
这会使所有迭代器和对位置(或第一个)及其后续元素的引用无效。
所以it
无效;使用它会导致未定义的行为。事实上,你碰巧得到了你所期望的纯粹的坏运气。
答案 1 :(得分:1)
您正在做的是未定义的行为,并且它“工作”完全是偶然的。你不能也绝不能永远依赖于此,因为它可以做任何事情。它的行为没有定义。
答案 2 :(得分:0)
作为实施细节,vector<int>::iterator
可以很容易地int*
。我认为在g++
中它是int*
周围的一个非常薄的包装器。如果是这种情况,那么删除三元素向量的中间元素意味着it
的指针数据成员指向与删除的元素相同的地址,这当然将包含以前在它之后的值,并且it2
也有效地引用了该值。
标准并不保证it
仍会引用任何内容,这就是为什么您不能依赖于此处观察到的行为的原因。但它解释了你所看到的。当你取消引用it
时,一个实现几乎不得不做出任何其他事情。但编译器确实每天都在不遗余力:例如调试库的版本,而一些优化技术依赖于假设你的代码是正确的。