std::list 上的 splice() 和迭代器失效

发布于 2024-07-06 10:42:20 字数 607 浏览 10 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

春花秋月 2024-07-13 10:42:20

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.

若相惜即相离 2024-07-13 10:42:20

问题是,如果迭代器仍然指向已移动的元素,则先前与“已移动”迭代器关联的“结束”迭代器已更改。 除非您编写一些复杂的循环,否则这实际上是一件坏事——特别是因为其他开发人员更难以理解。

我认为更好的方法是使用指向移动迭代器之前和之后的元素的迭代器。

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.

泪冰清 2024-07-13 10:42:20

我有一个列表数组(元素的等价类),并且我使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文