spled()on std :: list和iterator invalidation

时间:2008-09-27 06:57:28

标签: c++ list containers iterator

list::splice()的3参数形式将单个元素从一个列表移动到另一个列表。 SGI's documentation明确声明所有迭代器,包括指向要移动的元素的仍然有效。 Roguewave's documentation没有说明splice()方法的迭代器失效属性,而C ++标准明确声明它使所有迭代器和对被拼接元素的引用无效。

splicing()实际上是按照SGI的定义工作的,但是我在微软STL实现的调试/安全SCL版本中得到了断言失败(解除引用无效迭代器)(严格遵循标准的字母)。

现在,我正在使用list,因为我想在列表之间移动一个元素,同时保留指向它的迭代器的有效性。该标准对最初的SGI规范进行了极其无益的改变。

我该如何解决这个问题?或者我应该务实并且坚持不懈(因为拼接在实践中使迭代器无效 - 甚至在MS的实现中,一旦关闭迭代器调试)。

3 个答案:

答案 0 :(得分:9)

好吧,根据thisthis链接,这似乎是标准中的一个缺陷。似乎“将头埋在沙中”是一个很好的策略,因为它将在新的库版本中修复。

答案 1 :(得分:2)

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

在我看来,更好的方法是使用指向移动迭代器之前和之后的元素的迭代器。

答案 2 :(得分:0)

我有一个列表数组(元素的等价类),我正在使用splice在列表之间移动元素。我有一个额外的迭代器数组,它允许我直接访问任何列表中的任何元素,并将其移动到另一个列表。没有一个列表同时被搜索和修改。我可以在拼接后重新初始化元素迭代器,但它有点难看......我想我会暂时这样做。