在列表迭代期间删除元素 - 安全
我想知道这样的事情是否安全......
// Iterating through a <list>
while ( iter != seq.end()) {
if ( test ) {
iter = seq.erase( iter );
} else {
++iter;
}
我知道以这种方式迭代向量会使迭代器无效,但是同样的事情会发生在列表中吗?我认为不是,因为列表是通过指针连续的,而不是在内存中彼此“相邻”,但任何保证都会有帮助。
I was wondering if something like this is safe...
// Iterating through a <list>
while ( iter != seq.end()) {
if ( test ) {
iter = seq.erase( iter );
} else {
++iter;
}
I know that iterating through a vector in this way would invalidate the iterator, but would the same thing occur in a list? I assume not since a list is sequential through pointers rather than being "next" to each other in memory, but any reassurance would be helpful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这很好,因为擦除方法返回一个新的有效迭代器。
This is just fine because the erase method returns a new valid iterator.
是 -
std::list::erase()
:“仅使迭代器和对已擦除元素的引用无效。”也就是说,您可能根本不应该这样做——您似乎试图模仿
std::remove_if()
。Yes --
std::list::erase()
: "Invalidates only the iterators and references to the erased elements."That said, you probably shouldn't do this at all -- you seem to be trying to imitate
std::remove_if()
.该标准定义了每个 STL 容器的
擦除
行为。对于std::list
,只有被擦除元素的迭代器才会失效。不过,erase
的返回值不必是可取消引用的值(也可以是list.end()
)。因此,要删除列表中的所有元素,以下内容绝对有效:
但要注意类似这样的事情(危险的陷阱):
如果是
l.end()
,则它会增加两次(第二次增加循环头)。咩。The standard defines
erase
behaviour for every STL container. Forstd::list
only iterators to the erased elements are invalidated. The return value oferase
needn't be a dereferencable one, though (it could belist.end()
).Therefore, to erase all elements in a list the following is absolutely valid:
BUT beware of something like this (dangerous pitfall):
If it is
l.end()
, it is incremented twice (second time by the loop head). Baamm.是的,这是执行此操作的标准方法。请参阅有效 STL,第 9 项(第 46 页)。
Yes, this is the standard way to do that. See Effective STL, Item 9 (p. 46).
是的,这是完全安全的。
erase()
函数返回一个迭代器,指向被擦除元素之后的元素。如果您没有将erase()
的结果重新分配给iter
,就会遇到麻烦。Yes, this is totally safe. The
erase()
function returns an iterator to the element succeeding the one which was erased. Had you not reassigned the result oferase()
toiter
, you'd have trouble.正如其他人所解释的,您的代码不会使函数中使用的迭代器无效。但是,如果集合是向量,则它确实会使其他迭代器无效,但如果集合是列表,则不会。
As others have explained, your code does not invalidate the iterator used in the function. However, it does invalidate other iterators if the collection is a vector, but not if the collection is a list.
正如其他人提到的,是的,它会起作用。但我建议使用 list::remove_if 代替,因为它更具表现力。
As others have mentioned, yes, it will work. But I'd recommend using list::remove_if instead, as it's more expressive.