7

std::for_eachや友人と一緒に使うのに適したファンクタを考える:

template <typename T> struct Foo {
    void operator()(T const& t) { ... }
};

std::for_each(v.begin(), v.end(), Foo<Bar>());

std::copyこれを友人と一緒に使用するのに適した出力イテレータに変換する標準的な方法はありますか? (または逆の適応)次のようなもの:

std::copy(v.begin(), v.end(), functor_output_iterator(Foo<Bar>()));

値がイテレータに代入されるたびにファンクターを呼び出します:

adapter(F f) : functor(f) { }
adapter& operator*()  { return *this; }
operator=(T const& t) { functor(t); }
operator++()          { }
...

または、代わりに:

std::for_each(..., some_adapter(std::ostream_iterator(std::cout)));

バックグラウンド:

出力反復子を使用してコレクションを公開するクラスがあります。

template <typename It> GetItems(It out) {
    MutexGuard guard(mutex);
    std::copy(items.begin(), items.end(), out);
}

これにより、呼び出し元は、特定のコンテナー タイプの使用を強制したり、ロックやその他の内部の詳細をいじったりすることなく、アイテムにアクセスできます。

たとえば、ユニークなアイテムのみを取得するには:

std::set<whatever> set;
obj->GetItems(std::inserter(set, set.end()));

これは、次のことを圧倒します。

ObjLock lock = obj->GetLock();
for (int i = 0; i < obj->GetItemCount(); ++i) {
    Item* item = obj->GetItem(i);
    ...

また、これらのアイテムをコピーするのではなく、集約できるようにしたいと考えています。(この質問を参照してください)。私が通常次のようなことをする場所:

std::for_each(v.begin(), v.end(), Joiner<Foo>());

これで、同じデータ要素に対して 2 つの別々のメソッドを作成できます。1 つは呼び出すメソッド、もう 1 つは呼び出すstd::copyメソッドstd::for_eachですが、イテレーターまたはファンクターを使用して、そのようなメソッドを 1 つだけ定義し、呼び出し元がいずれかを渡すことができるようにするとよいでしょう。ファンクターまたはイテレーターを適切なタイプに必要に応じて適応させます。

私が今行っていることは、アグリゲーターを出力イテレーターまたはファンクターとして使用できるように定義することですが、これは望ましくない複雑さにつながります。

4

1 に答える 1

5

boost::function_output_iteratorはどうですか?

于 2010-02-08T00:12:32.800 に答える