insert_iterator无效规则

insert_iterator invalidation rules

本文关键字:规则 无效 iterator insert      更新时间:2023-10-16

STL 容器执行哪些操作可以使引用该容器的C++ std::insert_iterator无效?如果一个insert_iterator的底层迭代器(受保护的成员iter)是否有效,受通常的迭代器失效规则的约束?

相关:std::insert_iterator 和迭代器失效给出了一个无效insert_iterator的示例,但没有阐明规则。

如果其底层迭代器(受保护的成员迭代器)是insert_iterator有效,

你是对的,这就是规范中列出受保护成员的原因,并且在insert_iterator上工作的功能(特别是operator=,因为其余的都是无操作)是根据访问iter的函数定义的

好吧,答案取决于您具体要问什么。

(为了解决这个问题,我想立即指出您的"相关"链接完全不相关。该链接处的代码问题与insert_iterator失效完全无关。这个问题的作者误解了这个问题,最终试图解决一个不存在的问题,而真正的问题仍然存在。我也为这个问题提供了额外的答案。

如果您从有效的迭代器container::iterator it创建insert_iterator ins,然后独立地对容器执行某些操作,以使it无效,则ins也将失效。这是很自然的期待。如果您独立执行,ins无法知道容器发生了某些事情。

但是,同时insert_iterator用于插入时具有自我修复性能。例如,如果使用insert_iterator ins将数据插入到vector中,即使向量经过重新分配,ins仍然有效。即,即使向量重新分配是一个大规模的迭代器无效事件,它也不会损害ins(当然,假设重新分配是由通过ins执行的插入触发的)。

这遵循标准插入算法

it = container->insert(it, value);
++it;

其中it是存储在insert_iterator 中的基础插入点迭代器。前插入和后插入迭代器也具有相同的"自我修复"属性。可能无效的内部迭代器会立即重新验证。

为了说明差异,请考虑这个简单示例

std::vector<int> v(10);
std::vector<int>::iterator it = v.begin() + 5;
for (unsigned n = 20; n > 0; --n)
  v.insert(it, rand());

此代码通常是无效的,因为容器很可能会在插入周期中重新分配,从而使it无效并使所有进一步的插入无效。

同时此代码

std::vector<int> v(10);
std::vector<int>::iterator it = v.begin() + 5;
std::insert_iterator<std::vector<int> > it_ins(v, it);
for (unsigned n = 20; n > 0; --n)
  *it_ins++ = rand();

保证正常工作,无论向量是否重新分配。