简体   繁体   English

当这个容器也是容器的一个元素时,为什么容器的迭代器无效?

[英]Why is iterator of container invalidated when this container is also an element of a container?

int main() {
    std::vector<std::vector<int>> v;
    v.push_back({1,2,3,4});

    auto it = v.at(0).begin();
    int size = v.at(0).size();
    std::cout<<size<<std::endl;
    for (int i = 0; i < size; ++it)
    {
        v.push_back({5,6,7,8});
        //std::cout<<*it<<std::endl;
    }

    return 0;
}

The iterator is broken when I push some elements into the outer container.当我将一些元素推入外部容器时,迭代器被破坏。 what should I do if I really want to iterate the container element inside of outer container and at the same time keep pushing back some new elements ?如果我真的想在外部容器内部迭代容器元素,同时继续推回一些新元素,我该怎么办? Many thanks!非常感谢!

When the outer vector resizes, it must do one of two things:当外部向量调整大小时,它必须执行以下两项操作之一:

  • copy the elements复制元素
  • move the elements移动元素

It can only move the elements if the type has nonthrowing move semantics (the move constructor is marked noexcept , etc).如果类型具有非抛出移动语义(移动构造函数被标记为noexcept等),它只能移动元素。

In this case, the element is a vector holding integers, which recursively depends on its elements.在这种情况下,元素是一个包含整数的向量,它递归地依赖于它的元素。 Since integer does not throw, the inner vector should be noexcept-movable too.由于 integer 不会抛出,因此内部向量也应该是 noexcept-movable 。 The standard requires the iterators to remain valid when moving such a vector.该标准要求迭代器在移动此类向量时保持有效。

You say iterator is broken in your example, but the real problem is a bug in your code:迭代器在你的例子中坏了,但真正的问题是你的代码中的一个错误:

for (int i = 0; i < size; ++it) // << HERE
{
    v.push_back({5,6,7,8});
    //std::cout<<*it<<std::endl;
}

You don't increment the loop variable, you increment the iterator, in an infinite loop您不增加循环变量,而是在无限循环中增加迭代器

what should I do if I really want to iterate the container element inside of outer container and at the same time keep pushing back some new elements ?如果我真的想在外部容器内部迭代容器元素,同时继续推回一些新元素,我该怎么办?

I see 3 possible solutions:我看到 3 种可能的解决方案:

  • use container that does not relocate elements when new ones are added, for example std::map<size_t,std::vector<int>> , you should be aware of different memory usage and access speed使用添加新元素时不重新定位元素的容器,例如std::map<size_t,std::vector<int>> ,您应该注意不同的内存使用和访问速度

  • use index of inner array instead of iterator使用内部数组的索引而不是迭代器

  • add data to a temporary vector in the loop and after you done append all data to the original vector将数据添加到循环中的临时向量,完成后将所有数据附加到原始向量

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

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