2009-05-08 12 views
1

私はC++スキルを近代化しようとしているので、「STLの方法」が私には分かりません。複数の寄付者から寄せ集める

私は複数のソースからコンテナ(通常はstd::vector)への寄稿を集めたいオブジェクトを持っています。各ソースはオブジェクトであり、これらのオブジェクトのそれぞれは、0から多くの寄与を返すメソッドget_contributions()を提供します。収集者は各投稿者にget_contributions()を呼び出し、結果を1つのコレクションに集約します。

質問は、get_contributions()の最高の署名は何ですか?

オプション1:std::vector<contribution> get_contributions() const

は、これが最も簡単ですが、それは採集コピーマスターコレクションに結果の各セットとしてコピーの多くにつながります。そして、はい、パフォーマンスはここで重要です。たとえば、コントリビュータが幾何学モデルであり、コントリビューションがレンダリングのためにそれらを三角形に変換することになった場合、スピードはカウントされ、貢献の数は膨大になります。

オプション2:template <typename container> void get_contributions(container &target) const

これは、各投稿者はtarget.push_back(foo)を呼び出すことにより、マスター・コンテナに直接の貢献を追加することができます。ここでの欠点は、コンテナを他のタイプの検査と操作にさらしていることです。私はできるだけ狭いインターフェイスを維持することを望むだろう。

オプション3:このソリューションでtemplate <typename out_it> void get_contributions(out_it &it) const

、アグリゲータは、マスターコレクションのstd::back_insert_iteratorを通過する、および個々の貢献は、各寄与のため*it++ = foo;をするだろう。これは私が今までに思いついた最高ですが、よりエレガントな方法が必要であるという気持ちが残っています。 back_insert_iteratorはクルージュのように感じます。

オプション3が最適ですか、それとも良い方法がありますか?このパターンには名前がありますか?

答えて

1

オプション3は、最も慣用的な方法です。 back_insert_iteratorを使用する必要はありません。いくつの要素を追加するか分かっている場合は、ベクトルのサイズを変更してから、代わりに通常のベクトル反復子を提供することができます。それではpush_backを呼び出さないようにします(コピーを保存する可能性もあります)。

back_insert_iteratorの主な利点は、必要に応じてベクトルを展開することです。

しかし、それはクルージングではありません。この目的のために設計されています。

小さな調整の1つは、イテレータを値渡ししてから関数が返ってくるときにそれを返すことです。

2

イテレータの範囲を定義する必要があるのは4番目です。 Alexandrescuのプレゼンテーションは"Iterators must go"でチェックしてください。

+0

リンクありがとうございます。それは思考を刺激するプレゼンテーションです。 –

0

私は、あなたのオプション3(あなたが値段で渡す出力イテレータを取る)と、それぞれの貢献と呼ぶファンクタを取るという2つの慣用的なSTL方法があると言います。

これらはそれぞれ、テンプレートとしてget_contributionsを実装するのが適切な場合にのみ適切です。

+0

OK、ファンクタが理にかなっています。私はそれを考えます。なぜ出力イテレータを値渡しするべきなのでしょうか?出力イテレータが状態を維持している場合、値渡しの場合、呼び出し中に発生した状態の変更は失われます。 –