非 void STL 擦除的安全等效项是什么?
假设我有一个 hash_map 和类似的代码,
// i is an iterator
i = hash_map.erase(i)
但是 GCC 的 STL 在擦除时不会返回迭代器,而是返回一个 void。 现在的代码是否
hash_map.erase(i++)
安全(即不会使迭代器无效或发生任何其他意外或不愉快的事情)? 请注意这是一个 hash_map。
Suppose I have a hash_map and a code like
// i is an iterator
i = hash_map.erase(i)
But GCC's STL doesn't return iterator in erase, but a void. Now is a code like
hash_map.erase(i++)
safe (i.e. does not invalidate the iterator or does any other unexpected or unpleasant things)? Please note this is a hash_map.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,这是安全的,因为在擦除当前值之前,
i
的值将被设置为下一个值。根据 有关散列容器的 SGI 文档,未擦除的元素不会发生失效,甚至也没有调整大小(没有说明插入是否会导致调整大小,所以要小心,我承认这是一种可能性)——但在后一种情况下,迭代顺序将会改变。 但这并不适用于此,除非您在遍历或其他过程中不遗余力地调整容器的大小。 :-)
Yes, this is safe, because the value of
i
will have been set to the next value, before the current value is erased.According to the SGI documentation about hashed containers invalidation does not occur for non-erased elements, nor even for resizing (there is no word on whether insertions cause resizing, so to be careful I admit that as a possibility)---but in the latter case, the iteration order will be changed. But this doesn't apply here, unless you go out of your way to resize the container during traversal or something. :-)
您可以封装擦除,为您使用的所有容器提供相同的接口:
这需要:
You can encapsulate erasing to provide the same interface for all containers you use:
This requires either:
我不想在游行中下雨,但我认为你的提议并不安全。
i++ 是后递增运算符,这意味着 i 在调用擦除之后递增。 但是擦除会使所有指向被擦除元素的迭代器无效。 因此,当 i 递增时,它不再有效。
如果你幸运的话,它可能会意外地正常工作,直到有一天它不再正常工作。
据我所知,没有办法解决这个问题,但类似:
Hate to rain on the parade, but I don't think what you propose is safe.
i++ is the post-increment operator, which means i is incremented after the call to erase. But erase invalidates all iterators pointing to the element being erased. So by the time i is incremented it's not valid any more.
If you're lucky it may work correctly by accident until one day it doesn't any more.
As far as I'm aware there is no way around this but something like: