2

イテレータで文字列を初期化しようとしていますが、次のようなものが機能します:

ifstream fin("tmp.txt");  
istream_iterator<char> in_i(fin), eos; 
//here eos is 1 over the end  
string s(in_i, eos);

しかし、これはしません:

ifstream fin("tmp.txt");
istream_iterator<char> in_i(fin), eos(fin);
/* here eos is at this same position as in_i*/
//moving eos forward 
for (int i = 0; i < 20; ++i)
{
    ++eos; 
}
// trying to initialize string with 
// pair of iterators gives me "" 
// result  
string s(in_i, eos);

ありがとうございました。

4

4 に答える 4

2

終了イテレータを適切な位置に進めることはできないと思います。イテレータを進めるとは、入力を読み取ることを意味し、両方のイテレータが同じストリームを参照しているため、1 つのイテレータを進めることは 2 番目のイテレータを進めることを意味します。どちらもストリーム内の同じ位置を参照することになります。

イテレータによって参照される n 個の項目に対して操作を行うイテレータ アダプタ (ブースト?) を作成または検索する意思がない限り、そのような文字列を初期化することはできない場合があります。または、他の方法で値を読み取り、後で文字列の値を設定します。

于 2009-11-09T19:20:12.453 に答える
0

標準 [24.5.1]/1 から:

[...] 引数のないコンストラクター istream_iterator() は、常にストリーム入力反復子オブジェクトの終わりを構築します。これは、終了条件に使用される唯一の正当な反復子です。[...] istream イテレータの主な特徴は、++ 演算子が等価性を維持しないという事実です。つまり、i == j は ++i == ++j をまったく保証しません。++ が使用されるたびに、新しい値が読み取られます。

[24.5.1]/3

2 つの end-of-stream イテレータは常に等しくなります。ストリームの終わりの反復子は、ストリームの終わりではない反復子と等しくありません。ストリームの終わりではない 2 つの反復子は、同じストリームから構築された場合に等しい

最初の段落では、ストリームの終わりのイテレータ以外は終了条件として使用できないと述べているため、最初の使用法は正しく、期待どおりです。この章の 3 番目の段落では、同じストリームへの 2 つの非ストリーム終了イテレータは、常に等しいことが保証されていると述べています。つまり、2 番目の使用法は言語の観点からは正しく、得られる結果が得られます。

段落 1 の最後の部分では、ストリームに存在する最後の要素の特定のケースを扱うi == jことを意味するものではありません。最初の反復子 ( または のいずれか)++i == ++jをインクリメントした後、データはその反復子によって消費されます。もう一方の反復子を進めると、ストリームの終わりに達するため、2 つの反復子は異なります。他のすべての場合 (ストリームに複数のデータムが残っている) では、.ij++i == ++j

また、文++i == ++jは同じ要素 (ストリーム) に対して 2 つの変更操作を実行するため、2 つの反復子のどちらがストリーム内の最初/2 番目のデータを取得するかではないことに注意してください。

于 2009-11-09T19:37:33.583 に答える