std::list
迭代器有一些非常好的属性 - 当删除任何其他元素,添加新元素时,甚至交换2个列表时,它们仍然有效(Iterator invalidation rules)!
考虑以下代码行为并且迭代器是通过指向实际节点的指针的形式实现的,当移动列表时它不会改变,我的猜测是迭代器在新容器中仍然有效移动std::list
,但我也可以通过访问实际上具有"期望"的无效内存来进入UB区域。值。
std::list<int> l1{3, 2, 1};
std::list<int> l2;
auto it = std::prev(l1.end());
std::cout<<l1.size()<<" "<<l2.size()<<" "<<*it<<std::endl;
l2 = std::move(l1);
std::cout<<l2.size()<<" "<<*it<<std::endl;
3 0 1
3 1
如果移动std::list
时迭代器仍然有效,标准是否可以保证?其他容器怎么样?
答案 0 :(得分:9)
对于通常的容器,只有swap
保证迭代器保持有效(并指向交换的容器)。
对于std::list
,特殊成员函数splice()
保证迭代器保持其预期含义。
通常,从rvalue构造容器不能保证迭代器;唯一的一般要求是新容器与最初构造的容器具有“相同的值”。
(您可以想象调试迭代器实现存储对容器的引用,并且该引用将在移动后变为悬空。)