2011-01-16 5 views
2
std::istream_iterator<std::string> ist(std::cin); 
std::istream_iterator<std::string> eof; 
std::vector<std::string> str_vec(ist, eof); 
std::ofstream ofs("a"); 
if (!ofs) { 
    throw std::runtime_error("Open file failed."); 
} 
std::ostream_iterator<std::string> ost(ofs, "\n"); 
for (size_t index = 0; index != str_vec.size(); ++index) { 
    //*ost = str_vec[index]; 
    *ost++ = str_vec[index]; 
} 

私は* ost ++を使用しても同じ結果を得ました。私はistream_iterator増分の意味を知っています。しかし、ostream_iteratorのインクリメントはどのような状況で使用されるべきですか?ostream_iteratorインクリメントはどのような状況で使用する必要がありますか?

ありがとうございます!

答えて

2

さらに実験をすると、イテレータを参照解除しても動作させる必要がないことが示されます。 :)

ost = str_vec[index]; 

これらすべてのノーオペレーションメソッドは、ストリームイテレータに他のイテレータと同様のインターフェイスを与えるために必要です。

手動ループの代わりに、std::copyアルゴリズムを使用することもできます。 (つまり、ほとんどすべてostream_iteratorのために良い、このソートの答えあなたの質問でいたよう:あなたはまったく独自のコードでそれらのイテレータを台無しにする必要はありません!)どのようにコピー機能を考慮

std::copy(str_vec.begin(), str_vec.end(), std::ostream_iterator<std::string>(ofs, "\n")); 

template <class InIter, class OutIter> 
void copy(InIter begin, InIter end, OutIter result) 
{ 
    for (InIter it = begin; it != end; ++it) 
     *result++ = *it; // <-- here, result might be almost any kind of iterator 
} 
+0

なぜ今ostream_iteratorを使うべきかについてはっきりしています。 std :: copyの例をありがとう。 – MasterBeta

2

インクリメント演算子は、ostream_iteratorではノーオペレーションですが、出力イテレータの要件を満たす演算子を提供する必要があります。たとえば、ポインタは有効な出力イテレータであり、それをインクリメントする必要があります。

+0

@Martin:参照してくださいhttp://stdcxx.apache.org/doc/stdlibref/ostream-iterator.html#idx1067 –

+0

@Martinをテンプレートが書かれている刻みと逆参照が必要な場合、それが明らかになるかもしれませんしかし、問題は、出力イテレータである 'ostream_iterator'についてです。したがって、あなたの 'ost ++; ost ++; ost ++; ost ++'の例は、未定義の動作です。 –

+0

@ Fred Larson:はい、それは完全に間違っていました。質問で最初に宣言された入力反復子と混同され、出力イテレータが表示されません。 –

1

あなたのアルゴリズムは "ostream iterator"をインクリメントするべきではありません。出力イテレータをインクリメントしてにする必要があります。したがって、後続の要素を出力する場合は、常に出力イテレータをインクリメントします。この方法では、アルゴリズムはstd::ostream_iteratorstd::vector<T>::iteratorT*ポインタをサポートします。 Astd::ostream_iteratorのインクリメントはノーオペレーションになる可能性がありますが、他の出力イテレータでは必ずしもそうではありません。

関連する問題