简体   繁体   English

insert_iterator无效规则

[英]insert_iterator invalidation rules

What actions to an STL container can invalidate a C++ std::insert_iterator referencing that container? 对STL容器的哪些操作会使引用该容器的C ++ std::insert_iterator无效? Is an insert_iterator valid iff its underlying iterator (protected member iter ) is, subject to the usual Iterator invalidation rules ? 如果其基础迭代器(受保护成员iter )受制于通常的迭代器失效规则 ,则insert_iterator是否有效?

Related: std::insert_iterator and iterator invalidation gives an example of an invalid insert_iterator but did not elucidate the rules. 相关信息: std :: insert_iterator和迭代器无效给出了一个无效insert_iterator的示例,但未阐明规则。

Is an insert_iterator valid iff its underlying iterator (protected member iter) is, 如果insert_iterator是其基础迭代器(受保护成员iter),则为有效,

You are correct, that's the reason that protected member is listed in the spec and the functions that work on the insert_iterator (specifically, operator= , since the rest is no-ops) are defined in terms of functions that access iter insert_iterator ,这就是为什么规范中列出了受保护的成员,并且在insert_iteratorinsert_iterator的函数(具体来说是operator= ,因为其余的都是无操作)是根据访问iter的函数定义的

Well, the answer depends on what specifically you are asking about. 好吧,答案取决于您具体询问的内容。

(To get this out of the way, I'd like to immediately note that your "Related" link is completely unrelated. The problem with the code at that link has absolutely nothing to do with insert_iterator invalidation. The author of that question misinterpreted the issue and ended up trying to solve a non-existent problem, while the real problem persisted. I provided an extra answer to that question as well.) (为避免这种情况,我想立即注意到您的“相关”链接是完全不相关的。该链接上的代码问题与insert_iterator无效完全无关。该问题的作者误解了问题,最后尝试解决一个不存在的问题,而真正的问题仍然存在。我也为该问题提供了额外的答案。)

If you create an insert_iterator ins from a valid iterator container::iterator it and then independently do something to the container that would invalidate it , then ins will also get invalidated. 如果您创建一个insert_iterator ins从有效的迭代器container::iterator it ,然后独立做一些事情,将无效的容器it ,然后ins也就会无效。 This is something that is natural to expect. 这是很自然的期望。 The ins has no way to know that something happened to the container if you do it independently. 如果您独立进行操作, ins无法知道容器中是否发生了某些事情。

However, at the same time insert_iterator has self-repairing properties when it is used for insertion. 但是,与此同时, insert_iterator用于插入时具有自我修复属性。 For example, if you use insert_iterator ins to insert data into a vector , ins remains valid even if vector goes through reallocation. 例如,如果使用insert_iterator ins将数据插入到vector ,则即使vector经过重新分配, ins仍然有效。 Ie even though vector reallocation is a massive iterator-invalidating event, it does not damage ins (assuming, of course, that the reallocation was triggered by an insertion performed through ins ). 即,即使向量重新分配是一个大规模的迭代器无效事件,它也不会损坏ins (当然,假设重新分配是由通过ins执行的插入触发的)。

This follows from the standard insertion algorithm 这是从标准插入算法得出的

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

where it is the underlying insertion point iterator stored inside insert_iterator . it是存储在insert_iterator内部的基础插入点迭代器。 Front-inserting and back-inserting iterators also have the same "self-healing" properties. 前插入和后插入迭代器也具有相同的“自我修复”属性。 A potentially invalid internal iterator gets immediately re-validated. 可能无效的内部迭代器将立即重新验证。

To illustrate the difference, consider this simple example 为了说明不同之处,请考虑以下简单示例

std::vector<int> v(10);
std::vector<int>::iterator it = v.begin() + 5;

for (unsigned n = 20; n > 0; --n)
  v.insert(it, rand());

This code is generally invalid, since it is very likely that the container will reallocate during insertion cycle, thus invalidating it and rendering all further insertions invalid. 此代码通常是无效的,因为它很可能在刺入循环容器将重新分配,因而无效it和渲染所有进一步插入无效。

At the same time this code 同时这段代码

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();

is guaranteed to work fine, regardless of whether the vector reallocates or not. 无论向量是否重新分配,都可以保证正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM