对STL容器执行哪些操作可能会使引用该容器的C ++ std::insert_iterator
无效? insert_iterator
有效,如果它的基础迭代器(受保护的成员iter
)是通常的Iterator invalidation rules?
相关:std::insert_iterator and iterator invalidation给出了无效insert_iterator
的示例,但没有阐明规则。
答案 0 :(得分:2)
如果insert_iterator的底层迭代器(受保护的成员iter)是
,则它是否有效
你是对的,这就是保护成员在规范中列出的原因以及在insert_iterator
上工作的函数(特别是operator=
,因为其余的是无操作)在访问iter
答案 1 :(得分:1)
嗯,答案取决于你具体询问的内容。
(为了解决这个问题,我想立即注意您的“相关”链接完全不相关。该链接上的代码问题与insert_iterator
失效完全无关。这个问题的作者误解了这个问题,最终试图解决一个不存在的问题,而真正的问题仍然存在。我也为这个问题提供了额外的答案。)
如果您从有效的迭代器insert_iterator ins
创建container::iterator it
,然后独立对容器执行某些操作会导致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();
无论向量是否重新分配,都能保证正常工作。