このサンプル プログラムは、別のベクターに含まれるベクターの要素への反復子を取得します。含まれているベクターに別の要素を追加し、以前に取得した反復子の値を出力します。
#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;
}
に対応するベクトルfoo_it
は変更されていないため、反復子は引き続き有効であると予想されます。ただし、このコードを実行すると、次の出力が得られます ( ideone でも):
*foo_it: 1
*foo_it: 0
参考までに、g++ バージョン 4.2 と 4.6、および clang 3.1 を使用してこの結果を取得しました。ただし、 g++ を使用して-std=c++0x
( ideone link )、および とclang
の両方-std=c++0x
を 使用すると、期待される出力が得られ-stdlib=libc++
ます。
ここで何らかの未定義の動作を呼び出したことがありますか? もしそうなら、これは現在定義されている動作 C++ 11 ですか? それとも、これは単にコンパイラ/標準ライブラリのバグですか?
編集C++03 では、ベクトルの要素が再割り当て時にコピーされるため、反復子が無効になっていることがわかります。ただし、これがC++ 11で有効かどうかを知りたいです(つまり、ベクトルの要素はコピーではなく移動されることが保証されており、ベクトルを移動してもイテレータは無効になりません)。