STL list :: splice - 迭代器有效性

时间:2013-03-25 10:29:34

标签: c++ list stl

我正在阅读“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

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

根据文件:

  

迭代器有效性

     

迭代器,指针和引用没有变化   在通话之前与集装箱有关。 迭代器,指针和   引用转移元素的引用一直指的是   那些相同的元素,但迭代器现在迭代到容器中   元素已转移到。

因此它应该仍然有效

2 个答案:

答案 0 :(得分:3)

这只是猜测,但他们可能已经写过这意味着it现在“无效”,因为它不再是mylist1的有效迭代器,而是变为有效mylist2的迭代器。

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

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 效果:i之前插入列表xposition指向的元素,并从{中删除元素{1}}。如果xposition == i,结果将保持不变。指针和对position == ++i的引用继续引用此相同元素,但作为*i的成员。 *this(包括*i本身)的迭代器继续引用相同的元素,但现在表现为i的迭代器,而不是*this

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

答案 1 :(得分:1)

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

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

  

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

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

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