3

私は頭が良く、出力イテレータを受け入れるメンバー関数を作成できると思っていました。このようにして、コレクションを返したり、参照によってコレクションを取得したりすることを避けることができました。例えば:

template <typename TOutIterator>
void getHeaderNames(TOutIterator destination);

template <typename TOutIterator>
void getHeaderValues(std::string const& name, TOutIterator destination);

これらの関数は、渡されたイテレータにその結果を書き込みます。このようにして、セット、ベクトル、または ostream のいずれに書き込んでいるのかを心配する必要はありません。

今、私はそれほど賢くないと感じています。テストで実装をスタブ化できるように、これらの関数を仮想化したいと考えています。残念ながら、テンプレート メンバー関数を仮想にすることはできません。これは理にかなっています。

これらの関数をジェネリックに保ち (何にでも書き込み)、同時に仮想化できるようにする方法はありますか? すべてをベクトルに書き込んで、向きを変えて標準出力などに書き込むことは避けたいと思います。

自分の状況をもっと明確に説明する必要がある場合はお知らせください。

4

3 に答える 3

1

Thomas Becker によって提案された(そして後でBoost.Range に実装された) ように、型消去を使用してポリモーフィック イテレータを操作できます。あなたはそれらの線に沿って何かになるでしょう:any_iterator

typedef any_iterator<
  std::string, // Value
  Writable,    // Access
  Forward,     // Traversal
> StringOutputIterator; // can represent any output iterator accepting strings

virtual void getHeaders(StringOutputIterator destination);

型消去の考え方は、関連のない型のセットに共通の基底クラスを持たせることです (テンプレートの使用により、C++ では非常に頻繁に発生します)。たとえばstd::function、同様の方法で関数ポインター、ファンクター、またはラムダを操作できるようにすることで、このイディオムを呼び出し可能なオブジェクトに適用します。

于 2012-06-14T15:18:41.063 に答える
0

それらを一般的に保つ1つの方法であり、私は通常これを実際に見ますが、ストリーム出力演算子(意味がある場合)を2つオーバーロードするか、。を取りますstd::ostream&

もちろん、それはあなたの正確な状況に依存します:あなたはイテレータがより理にかなっているアルゴリズムを書いていますか?または、オブジェクトのコンテンツをダンプしたいだけですか?

于 2012-06-14T15:20:16.547 に答える