使用嵌套向量的迭代器的意外行为

Dav*_*own 4 c++ iterator vector c++11

此示例程序获取另一个向量中包含的向量元素的迭代器.我向包含向量添加另一个元素,然后打印出以前获得的迭代器的值:

#include <vector>
#include <iostream>

int main(int argc, char const *argv[])
{
    std::vector<std::vector<int> > foo(3, std::vector<int>(3, 1));
    std::vector<int>::iterator foo_it = foo[0].begin();
    std::cout << "*foo_it: " << *foo_it << std::endl;
    foo.push_back(std::vector<int>(3, 2));
    std::cout << "*foo_it: " << *foo_it << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

由于未修改向量对应,foo_it我希望迭代器仍然有效.但是,当我运行此代码时,我得到以下输出(也在ideone上):

*foo_it: 1
*foo_it: 0
Run Code Online (Sandbox Code Playgroud)

作为参考,我使用g ++版本4.2和4.6以及clang 3.1获得此结果.但是我用g ++使用-std=c++0x(ideone链接)得到了预期的输出,并且clang在使用-std=c++0x和时得到了 -stdlib=libc++.

我在这里以某种方式调用了一些未定义的行为吗?如果是这样,现在定义的行为C++ 11?或者这只是一个编译器/标准库错误?

编辑我现在可以看到,在C++ 03中,迭代器无效,因为在重新分配时复制了向量的元素.但是我仍然想知道这在C++ 11中是否有效(即向量的元素保证被移动而不是复制,并且移动向量而不是使它的迭代器无效).

Luc*_*ore 5

push_back 使迭代器无效,就这么简单.

std::vector<int>::iterator foo_it = foo[0].begin();
foo.push_back(std::vector<int>(3, 2));
Run Code Online (Sandbox Code Playgroud)

在此之后,foo_ti不再有效.任何insert/push_back都有可能在内部重新分配向量.


Rob*_*obᵩ 5

由于对应的向量foo_it没有被修改

错误.的push_back破坏对应于向量foo_it.被摧毁foo_it时变得无效 foo[0].