【问题标题】:STL list::splice - iterator validitySTL list::splice - 迭代器有效性
【发布时间】:2013-03-25 10:29:33
【问题描述】:

我正在阅读“list::splice”的工作原理,但我不明白:

  mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
                                // mylist2 (empty)
                                // "it" still points to 2 (the 5th element)

  mylist2.splice (mylist2.begin(),mylist1, it);
                                // mylist1: 1 10 20 30 3 4
                                // mylist2: 2
                                // "it" is now invalid.
  it = mylist1.begin();
  std::advance(it,3);           // "it" points now to 30

  mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
                                // mylist1: 30 3 4 1 10 20

在第一个和第三个拼接中 it 迭代器仍然有效,但为什么它在第二个拼接中不存在?

根据文档:

迭代器有效性

迭代器、指针和引用没有变化 调用前与容器相关。 迭代器、指针和 引用转移元素的引用继续引用 那些相同的元素,但迭代器现在迭代到容器中 元素已被转移到。

因此它应该仍然有效

【问题讨论】:

  • 那个资源是出了名的不准确。用一磅盐吃掉它所说的任何东西。
  • @JohnnyPauling:我在 cppreference 上没有看到这一点,他们明确表示 no 迭代器被 splice 无效。
  • 在哪里?我只看到它说“没有迭代器或引用失效”。
  • @DanielFrey 问题依然存在,迭代器在第二次拼接后无效,而 cppreference 声明它应该保持有效

标签: c++ list stl


【解决方案1】:

这只是一个猜测,但他们可能会这样写来暗示 it 现在是“无效的”,因为它不再是 mylist1 的有效迭代器,而是成为 @987654323 的有效迭代器@。

但是,我猜你已经知道了,它是一个有效的迭代器,所以措辞具有误导性。但是,您需要小心,因为这意味着在第二次拼接操作之后,例如,您不能再这样做:

std::distance( mylist1.begin(), it );

但需要使用

std::distance( mylist2.begin(), it );

因为第一个是非法的。

标准在以下方面明确定义了它:

23.3.5.5 列表操作 [list.ops]

void splice(const_iterator position, list& x, const_iterator i);
void splice(const_iterator position, list&& x, const_iterator i);

7效果:position 之前插入列表xi 指向的元素,并从x 中删除该元素。如果position == iposition == ++i,结果不变。指向*i 的指针和引用继续引用同一元素,但作为*this 的成员。 *i 的迭代器(包括 i 本身)继续引用同一个元素,但现在作为 *this 的迭代器,而不是 x 的迭代器。

因此,如果您的编译器/STL 使迭代器无效,这显然是一个错误。

【讨论】:

  • 我同意你的观点,一定是 MSVC 的 bug
【解决方案2】:

显然(因为我使用的是 MSVC2012)行为不同:

http://msdn.microsoft.com/en-us/library/72fb8wzd.aspx

在所有情况下,只有指向 spliced 的迭代器或引用 元素变得无效。

因此,当我对从一个容器移动到另一个容器的元素有迭代器时,这些迭代器将变得无效。

不过,我很想知道这种行为是否是标准行为。

【讨论】:

  • 为什么微软库以不同的方式实现?有什么理智的理由吗?
  • 标准中存在缺陷,MSVC2012 显然遵循了这一点:stackoverflow.com/a/143165/4130137
猜你喜欢
  • 2010-09-13
  • 2012-05-13
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2020-11-22
  • 2022-07-18
  • 2012-03-16
相关资源
最近更新 更多