0

私は標準を見ましたが、明白な答えは見当たりませんでした。

私がこれをしたとしましょう:

std::istream_iterator<char> is(file);
while(is != std::istream_iterator<char>()) {
    ++is;
}

現在isはストリームの最後にあり、に等しくなりstd::istream_iterator<char>()ます。もう一度インクリメントするとどうなりますか?それはまだ等しいstd::istream_iterator<char>()ですか?またはos結果は未定義ですか?

がストリームの最後にある*is場合、標準はそれが未定義の動作であると明示的に述べています。isしかし、ストリームの終わりを超えて反復することに関しては何も見ていません...

編集

私はこのようなことをするいくつかのコードに出くわしたので尋ねます:

// skip 2 input chars
++is;
++is;
if(is != std::istream_iterator<char>()) {
    // continue using is and do some work...but what if the first
    // increment made it EOS? is this check valid?
}
4

2 に答える 2

4

入力反復子の要件に関する C++03 の表 72 は、の前提条件が参照解除可能で++rあることを示していrます。についても同じ前提条件が成り立ちますr++

今、24.5.1/1について言いますistream_iterator

operator*ストリームの終わりでの結果は定義されていません。

operator++結論として、ストリームの終わりの反復子に対する の影響は定義されていません。

入力反復子の要件に関する C++03 の表 72 は、の前提条件が参照解除可能で++rあることを示していrます。についても同じ前提条件が成り立ちますr++

今、24.5.1/1について言いますistream_iterator

operator*ストリームの終わりでの結果は定義されていません。

operator++結論として、ストリームの終わりの反復子に対する の影響は定義されていません。


この結論は、その動作を示す入力イテレータを受け取るアルゴリズムを記述または使用してから istream イテレータを渡す場合にのみ、動作が未定義になると思うことに注意してください。istream イテレーター自体を明示的に使用するだけで、それを入力イテレーターとして扱い、その不変条件に依存することなく、上記の結論は正しくないと思います (rたとえば、逆参照可能であることを必要としないクラスがある場合があります)。 )。

しかし、istream iterator の記述方法を見るとoperator++、ストリーム値の最後に到達した後で を呼び出すと、どちらも未定義の動作になります。operator==と同等であると定義されているため

x.in_stream == y.in_stream

反復処理されたストリームへのポインターはどこin_streamにあり、動作とセマンティクスを「説明のみ」定義するために標準テキストに公開されます。今、私が考えることができる唯一の実装は、ストリームポインタとしてヌルポインタを格納するストリームの終わりのイテレータを使用することです。しかしoperator++、次の効果を持つ何かをすることとして定義されています

*in_stream >>value

ここで、ストリームの終わりの状態に入り、in_streamnull ポインターに設定すると、その結果は未定義の動作になります。

したがって、istream イテレータを単独で使用したとしても、ストリームの終わりの値を超えてインクリメントできるという保証はないようです。

于 2009-08-20T22:37:24.263 に答える
3

定義されていない場合、定義されていません:-)標準(C ++ 0Xの最新ドラフト)の言葉では、強調は私のものです:

未定義の動作

この国際規格が要件を課していない、誤ったプログラム構成または誤ったデータの使用時に発生する可能性があるような動作。この国際規格が動作の明示的な定義の説明を省略している場合も、未定義の動作が予想される場合があります。

于 2009-08-20T18:01:41.387 に答える