std::list 上的 splice() 和迭代器失效
list::splice()
的 3 参数形式将单个元素从一个列表移动到另一个列表。 SGI 文档明确指出所有迭代器,包括指向正在移动的元素的一个仍然有效。 Roguewave 文档 没有提及任何有关 splice()
方法,而 C++ 标准明确指出它会使所有迭代器和对被拼接元素的引用无效。
splicing() 实际上按照 SGI 的定义工作,但我在微软 STL 实现的调试/安全 SCL 版本(严格遵循标准的字母)中遇到断言失败(取消引用无效迭代器)。
现在,我使用列表正是因为我想在列表之间移动元素,同时保留指向它的迭代器的有效性。 该标准对原始 SGI 规范进行了极其无益的更改。
我该如何解决这个问题? 或者我应该务实一点,把头埋在沙子里(因为在实践中,拼接不会使迭代器失效——即使在 MS 的实现中,一旦关闭迭代器调试,也不会)。
The 3-argument form of list::splice()
moves a single element from one list to the other. SGI's documentation explicitly states that all iterators, including the one pointing to the element being moved remain valid. Roguewave's documentation does not say anything about iterator invalidation properties of splice()
methods, whereas the C++ standard explicitly states that it invalidates all iterators and references to the element being spliced.
splicing() in practice works as defined by SGI, but I get assertion failure (dereferencing invalid iterator) in debug / secure SCL versions of microsoft's STL implementation (which strictly follows the letter of the standard).
Now, I'm using list exactly because I want to move an element between lists, while preserving the validity of the iterator pointing to it. The standard has made an extremely unhelpful change to the original SGI's specification.
How can I work around this problem? Or should I just be pragmatic and stick my head in the sand (because the splicing does not invalidate iterators in practice -- not even in the MS's implementation, once iterator debugging is turned off).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的,根据 这个和这个< /a> 链接。 看来“把头埋在沙子里”是一个很好的策略,因为它将在新的库版本中得到修复。
Ok, this seems to be a defect in the standard, according to this and this link. It seems that "sticking the head in the sand" is a good strategy, since it will be fixed in new library versions.
问题是,如果迭代器仍然指向已移动的元素,则先前与“已移动”迭代器关联的“结束”迭代器已更改。 除非您编写一些复杂的循环,否则这实际上是一件坏事——特别是因为其他开发人员更难以理解。
我认为更好的方法是使用指向移动迭代器之前和之后的元素的迭代器。
The problem is that if the iterator still points to the element that was moved, then the "end" iterator previously associated with the "moved" iterator has changed. Unless you write some complex loop, this is actually a bad thing to do -- especially since it will be more difficult for other developers to understand.
A better way in my opinion is to use the iterators pointing to the elements prior and after the moved iterator.
我有一个列表数组(元素的等价类),并且我使用 splice 在列表之间移动元素。 我有一个额外的迭代器数组,它使我可以直接访问任何列表中的任何元素并将其移动到另一个列表。 不会同时搜索和修改任何列表。 我可以在拼接后重新初始化元素迭代器,但这有点难看......我想我暂时会这样做。
I have an array of lists (equivalence classes of elements), and I'm using splice to move elements between the lists. I have an additional array of iterators which gives me direct access to any element in any of the lists and to move it to another list. None of the lists is searched and modified at the same time. I could reinitialize the element iterator after splice, but it's kinda ugly.. I guess I'll do that for the time being.