嗨,我在C++初级读本中读到,向向量添加元素会使迭代器失效。我不明白为什么删除元素不会使它们失效,因为下面的代码是有效的
std::vector<int> a = {1,2,3,4,5,6};
auto b = a.begin();
while (b != a.end()){
if (*b%2 != 0)
a.erase(b);
else
b++;
}
注意:此代码来自C++引物本身和cpp reference
嗨,我在C++初级读本中读到,向向量添加元素会使迭代器失效。我不明白为什么删除元素不会使它们失效,因为下面的代码是有效的
std::vector<int> a = {1,2,3,4,5,6};
auto b = a.begin();
while (b != a.end()){
if (*b%2 != 0)
a.erase(b);
else
b++;
}
注意:此代码来自C++引物本身和cpp reference
5条答案
按热度按时间0yycz8jy1#
实际上这不是问题的答案,但我认为值得一提的是,在现代C++中,你应该通过使用算法和基于范围的for循环来避免迭代器。
o8x7eapl2#
一般来说,此代码片段
是无效的。它之所以有效是因为容器std::vector满足连续范围的概念。如果不使用vector,而是使用例如
std::list<int>
,则迭代器b
将无效。应该这样写
n53p2ov03#
常见用法。来自cppreference:(erase)'使擦除点或擦除点之后的迭代器和引用无效,包括end()迭代器。
还有人指出应该这样写:
如果用户更喜欢“while”而不是“for”,请进行调整。如果性能是最重要的,则可以从末尾开始,但这可能不太适合缓存。
编辑:代码片段字面上是cppreference链接。
jyztefdp4#
向向量添加元素可能会导致向量完全重新分配,这会使之前持有的所有迭代器失效。
如果删除向量的一个条目,则erase方法返回:a)到下一个有效元素的迭代器B)结束迭代器。
但你必须使用它。在你的情况下:
tjrkku2a5#
正如许多人指出的那样,它是偶然工作的。不要在生产中这样做。迭代器被设计成尽可能轻量级的,这样就不会有一个标志说它是无效的。那将是太浪费了。
std::vector迭代器可能被实现为带有一些辅助函数的指针。删除一个元素将移动所有元素,以便相同的指针现在指向旧元素所在的新元素。它之所以有效,是因为元素存储在连续的内存中,没有间隙。