STL列表:拼接迭代器有效性
STL list::splice - iterator validity
我正在阅读"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迭代器仍然有效,但为什么它不在第二个拼接中?
根据文件:
迭代器有效性
迭代器、指针和引用没有更改与调用前的容器相关迭代器、指针和引用已转移元素的引用继续引用那些相同的元素,但迭代器现在迭代到容器中元素已转移到。
因此它应该仍然是有效的
这只是一个猜测,但他们可能已经写了这篇文章来暗示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效果:在
position
之前插入列表x
中i
指向的元素,并从x
中删除该元素。如果是position == i
或position == ++i
,则结果不变。指向*i
的指针和引用继续引用相同的元素,但作为*this
的成员。*i
的迭代器(包括i
本身(继续引用同一个元素,但现在充当*this
的迭代者,而不是x
的迭代。
因此,如果编译器/STL使迭代器无效,那么这显然是一个错误。
显然(因为我使用的是MSVC2012(,行为是不同的:
http://msdn.microsoft.com/en-us/library/72fb8wzd.aspx
在所有情况下,只有指向拼接的迭代器或引用元素变得无效。
因此,当我对从一个容器移动到另一个容器的元素使用迭代器时,这些迭代器就会失效。
不过,我很想知道这种行为是否是标准行为。
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 列表的有效性在插入后开始迭代器
- 没有迭代器失效是否意味着推进迭代器的有效性?
- 螺纹安全与迭代器有效性
- 迭代器有效性
- 删除元素后 std::map::迭代器的有效性
- c++迭代器有效性问题
- std::vector<std::vector 的迭代器有效性<T>>
- STL列表:拼接迭代器有效性
- 通过插入保持std::list迭代器的有效性