0

对 STL 容器的哪些操作会使std::insert_iterator引用该容器的 C++ 无效?insert_iterator如果它的底层迭代器(受保护iter的成员)符合通常的迭代器无效规则,那么它是有效的吗?

相关:std::insert_iterator 和 iterator invalidation给出了一个无效insert_iterator但没有阐明规则的例子。

4

2 回答 2

2

当其底层迭代器(受保护的成员 iter)是时, insert_iterator 是否有效,

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

于 2012-07-04T22:13:18.967 回答
1

嗯,答案取决于你具体问的是什么。

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

如果你insert_iterator ins从一个有效的迭代器创建一个container::iterator it,然后独立地对容器做一些会使无效的事情it,那么ins也会被无效。这是很自然的事情。如果您独立进行,ins则无法知道容器发生了什么事。

但同时在insert_iterator用于插入时具有自修复特性。例如,如果您使用insert_iterator ins将数据插入到 avector中,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();

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

于 2012-07-04T22:38:40.233 回答