[英]Do STL iterators guarantee validity after collection was changed?
Let's say I have some kind of collection and I obtained an iterator for the beginning of it. 假设我有一些集合,我在它的开头就获得了一个迭代器。 Now let's say I modified the collection.
现在让我们说我修改了这个集合。 Can I still use the iterator safely, regardless of the type of the collection or the iterator?
无论集合的类型还是迭代器,我还能安全地使用迭代器吗?
To avoid confusion, here is the order of operations I talk about: 为避免混淆,这是我谈到的操作顺序:
Depends on the container. 取决于容器。 eg if it's a
vector
, after modifying the container all iterators can be invalidated. 例如,如果它是一个
vector
,则在修改容器之后,所有迭代器都可以无效。 However, if it's a list
, the iterators irrelevant to the modified place will remain valid. 但是,如果它是一个
list
,则与修改后的位置无关的迭代器将保持有效。
A vector's iterators are invalidated when its memory is reallocated.
当重新分配内存时,向量的迭代器将失效。 Additionally, inserting or deleting an element in the middle of a vector invalidates all iterators that point to elements following the insertion or deletion point.
此外,在向量中间插入或删除元素会使指向插入或删除点后面的元素的所有迭代器无效。 It follows that you can prevent a vector's iterators from being invalidated if you use
reserve()
to preallocate as much memory as the vector will ever use, and if all insertions and deletions are at the vector's end.因此,如果使用
reserve()
预分配尽可能多的内存,并且所有插入和删除都在向量的末尾,则可以防止向量的迭代器失效。 [1][1]
The semantics of iterator invalidation for
deque
is as follows.deque
的迭代器失效的语义如下。Insert
(includingpush_front
andpush_back
) invalidates all iterators that refer to adeque
.Insert
(包括push_front
和push_back
)使引用deque
所有迭代器无效。Erase
in the middle of adeque
invalidates all iterators that refer to thedeque
.在
deque
中间Erase
使所有引用deque
迭代器无效。Erase
at the beginning or end of adeque
(includingpop_front
andpop_back
) invalidates an iterator only if it points to the erased element.在
deque
的开头或结尾处Erase
(包括pop_front
和pop_back
)只有在指向已擦除元素时才会使迭代器无效。 [2][2]
List
s have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed.List
具有重要的属性,即插入和拼接不会使列表元素的迭代器无效,甚至删除也只会使指向被删除元素的迭代器无效。 [3][3]
Map
has the important property that inserting a new element into amap
does not invalidate iterators that point to existing elements.Map
具有重要的属性,即将新元素插入到map
中不会使指向现有元素的迭代器无效。 Erasing an element from a map also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.从地图中删除元素也不会使任何迭代器无效,当然,除了实际指向正在被删除的元素的迭代器之外。 [4] (same for
set
,multiset
andmultimap
)[4] (同样适用于
set
,multiset
和multimap
)
That depends on the collection in question. 这取决于有问题的集合。 Just for example, modifying a
std::vector
(eg, adding an element somewhere) can invalidate all iterators into that vector. 例如,修改
std::vector
(例如,在某处添加元素)可以使所有迭代器无效到该向量中。 By contrast, with a std::list
, iterators remain valid when you add another element to the list. 相反,对于
std::list
,当您向列表中添加另一个元素时,迭代器仍然有效。 In some cases, the rules are even more complex (eg, if memory serves, with a std::deque
, adding to the beginning or end leaves existing iterators valid, but adding anywhere else can invalidate them -- but my memory is sufficiently poor that you should check before depending on that). 在某些情况下,规则甚至更复杂(例如,如果内存服务,使用
std::deque
,添加到开头或结尾使现有迭代器有效,但添加其他任何地方都可能使它们无效 - 但我的记忆力很差你应该检查之前,取决于那个)。
No, iterators are only good while the iterated container is unchanged. 不,迭代器只有在迭代容器不变的情况下才有效。 If a collection is modified, the iterator should be obtained anew.
如果修改了集合,则应重新获取迭代器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.