std::list迭代器有一些非常好的属性 - 当删除任何其他元素,添加新元素时,甚至当交换2个列表时,它们仍然有效(迭代器失效规则)!
考虑以下代码行为并且迭代器是通过指向实际节点的指针的形式实现的,当移动列表时,该指针不会改变,我猜测迭代器在std::list移动a时在新容器中仍然有效,而且我可以通过访问实际具有"预期"值的无效内存进入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
Run Code Online (Sandbox Code Playgroud)
如果std::list移动时迭代器保持有效,它是否由标准保证?其他容器怎么样?
对于通常的容器,只swap保证迭代器保持有效(并指向交换的容器).
因为std::list,特殊成员函数splice()保证迭代器保持其预期含义.
通常,从rvalue构造容器不能保证迭代器; 唯一的一般要求是新容器与最初构造的容器具有"相同的值".
(您可以想象调试迭代器实现,它存储对容器的引用,并且该引用在移动后将变为悬空.)