これは、手作りのアルゴリズムを使用した非並列実装です。私は、より精通した誰かがfunctional
よりエレガントな解決策を思い付くことができると確信しています。問題transform
は、戻る関数では使用できず、void
2つの範囲を取り、それらを相互に適用する別の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;
}