关于c ++:insert_iterator失效规则

insert_iterator invalidation rules

对STL容器执行哪些操作会使引用该容器的C ++ std::insert_iterator无效? 如果insert_iterator有效,并且其基础迭代器(受保护的成员iter)受制于通常的迭代器失效规则,是否有效?

相关信息:std :: insert_iterator和迭代器无效给出了无效insert_iterator的示例,但未阐明规则。


Is an insert_iterator valid iff its underlying iterator (protected member iter) is,

没错,这就是规范中列出受保护成员并且在insert_iterator上起作用的函数(特别是operator=,因为其余均为无操作)是根据访问


好吧,答案取决于您具体询问的内容。

(为避免这种情况,我想立即注意到您的"相关"链接是完全不相关的。该链接上的代码问题与insert_iterator无效完全无关。该问题的作者错误地解释了这个问题,最终试图解决一个不存在的问题,而真正的问题仍然存在。我也为该问题提供了一个额外的答案。)

如果从有效的迭代器container::iterator it创建insert_iterator ins,然后独立地对容器执行会使it失效的操作,则ins也将失效。这是很自然的期望。如果单独执行ins,则无法知道容器中发生了什么。

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

这是从标准插入算法得出的

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

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

为了说明不同之处,请考虑以下简单示例

1
2
3
4
5
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无效并使所有其他插入变为无效。

同时这段代码

1
2
3
4
5
6
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();

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