[C++] ベクトルとリストのend()イテレータのセマンティクス


Answers

Question

C ++標準によると、ベクトルのpush_back()を呼び出すと、ベクトルの新しいサイズがその容量よりも大きくなった場合にイテレータが無効になりますが、リスト上ではイテレータは決して無効になりません。 次に、次のコードスニペットを考えてみましょう。

1。

vector<int> v{1,2,3};
v.reserve(100);
for (int i: v) {
    v.push_back(i);
}

2。

list<int> l{1,2,3};
for (int i: l) {
    l.push_back(i);
}

私はgcc 4.8でそれを試したところ、コード1はv{1,2,3,1,2,3}で終わっていたが、コード2は無限ループに入っていた。 説明は非常に簡単です: vector end()イテレータはメモリ位置を指します。ループの範囲内で一度だけ評価されるので、ベクトルの3番目の要素を過ぎると停止します。 一方listおそらく最後の要素の後に常に置かれるエンドイテレータとしての何らかのヌルトークンがあるので、ループはそれに到達しません。

結果は簡単ですが、私の疑問は標準がこれについて何を言いますか? それはすべての標準的なライブラリの実装でそうなっているのでしょうか、あるいはこの動作は定義されていませんか? push_back()をそのようなコンテナ(通常はとにかく避けたいpush_back()に呼び出すことができるループを書くときに、私は何を期待するべきですか?