3

次のコードを検討してください。

std::set<int> s;
auto it = s.begin();
s.insert(1);
s.insert(2);
std::cout << *it << std::endl;

出力は(少なくとも私にとっては)です2。ここで何が起こっているのですか?it逆参照するとどのような状態になりますか?

空のセットを呼び出すとbegin()、 に相当するイテレータが得られることを知っていますend()insertまた、 aを呼び出してもsetイテレータが無効にならないこともわかっています。end()に要素を挿入したsetため、未定義の動作が発生しているにもかかわらず、イテレータはどういうわけか同等のままですか? それは標準で定義されていますか?

4

3 に答える 3

7

ここで呼び出すとs.begin()、コンテナーが空であるため、終了イテレーターが返されます。この反復子は、挿入によって無効化されません。各挿入後、この反復子は終了反復子のままです。

このイテレータを逆参照すると、プログラムで未定義の動作が発生します (終了イテレータは逆参照できません)。

于 2012-11-16T21:37:02.617 に答える
1

イテレータitは に等しいままs.end()です。終了イテレータの逆参照は未定義の動作です。それがあなたが見ているものです。たとえば、これを試してください

if (it == s.end())
{
    cout << "at end\n";
}

これは法規です。

于 2012-11-16T21:37:43.737 に答える
0

最初のケースの「it」は、ファントム要素のアドレスである s.end() を指します。ファントム要素のアドレスは、コンテナ内の最後の要素の後の「存在しない」要素のアドレスに他なりません。セットが変更されると、挿入前に最初に s.end() を指していた「it」は、挿入後の s.end() と同じではない場合があります。

したがって、「それ」を逆参照すると、未定義の動作が発生します。

于 2012-11-16T21:45:28.683 に答える