0

私は持っている:

  • unique_ptrObjectAの s のベクトル

  • ObjectB の新しく構築されたデフォルトのベクトルのベクトル、および

  • signature を持つオブジェクト B の関数void f(unique_ptr<ObjectA> o)

(以降、Object という単語は省略します)

Bvec[i].f(Avec[i])すべて0 < i < lengthを並行して行うにはどうすればよいですか?

を使用してみtransform(Bvec.begin(), Bvec.end(), A.begin(), B.begin(), mem_fun_ref(&B::f))ましたが、多くのエラーが発生し、正しい A をパラメーターとして渡すかどうか、ましてやそれらを移動できるかどうかわかりません。 (&B::f(A.begin())最後のパラメーターとしても機能しません。

for_each を使用してからラムダ関数を使用することも考えましたが、対応する要素を取得する方法がわかりません。カウンターをインクリメントすることを考えましたが、うまく並列化できないと思います (間違っている可能性があります)。

もちろん、0 から最後まで for ループを使用することはできますが、欠けている単純なものがあると確信しており、単純な for ループとは並列ではありません。

ありがとう。

4

1 に答える 1

0

これは、手作りのアルゴリズムを使用した非並列実装です。私は、より精通した誰かがfunctionalよりエレガントな解決策を思い付くことができると確信しています。問題transformは、戻る関数では使用できず、void2つの範囲を取り、それらを相互に適用する別のstdlib関数を思い出せないことです。これを本当に並列化したい場合は、apply_to関数で実行する必要があります。タスクを起動しasyncます(たとえばstd::async(*begin++, *begin2++)、これについての経験がなく、gcc 4.6.2で動作させることはできませんが、動作する可能性があります。

#include <iterator>
#include <memory>
#include <vector>
#include <algorithm>
#include <functional>


// this is very naive it should check call different versions
// depending on the value_type of iterator2, especially considering
// that a tuple would make sense
template<typename InputIterator1, typename InputIterator2>
void apply_to(InputIterator1 begin, InputIterator1 end, InputIterator2 begin2) {
  while(begin != end) {
    (*begin++)(*begin2++);
  }
}

struct Foo {

};

struct Bar {
  void f(std::unique_ptr<Foo>) { }
};


int main()
{
  std::vector< std::unique_ptr<Foo> > foos(10);
  std::vector< Bar > bars(10);
  std::vector< std::function<void(std::unique_ptr<Foo>) > > funs;

  std::transform(bars.begin(), bars.end(), std::back_inserter(funs),
                 // non-const due to f non-const, change accordingly
                 [](Bar& b) { return std::bind(&Bar::f, &b, std::placeholders::_1); });

  // now we just need to apply each element in foos with funs
  apply_to(funs.begin(), funs.end(), std::make_move_iterator(foos.begin()));


  return 0;
}
于 2011-12-07T22:50:37.390 に答える