2011-12-07 13 views
0

我有:C++传递unique_ptrs作为参数的向量相对应的另一相等长度向量的元素(特别是平行地)

矢量的 unique_ptr
  • 小号对象A的

  • 新默认构建的载体的载体的ObjectB,

  • 对象B中具有签名void f(unique_ptr<ObjectA> o)的函数。

(从这里略去了对Word对象)

我该怎么做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然后lambda函数,但不知道如何获得相应的元素。我想增加一个计数器,但是我认为这并不好(我可能是错的)。

当然,我可以使用for循环从0到结束,但我很确定有一个简单的东西我错过了,它不是一个简单的for循环。

谢谢。

+0

你会意识到,通过传递的唯一指针,你*所有权转让*这些指针从列表中移出,并且进入该函数,是否正确?另外,它也不与'std :: transform'并行。 –

+0

@NicolBolas是的,我使用了转移,但是我不知道转换是(MTG player?off topic,nm) – chemelnucfin

+0

你的意思是当你说并行吗?'transform'会像其他每一个stdlib算法一样工作,而'transform'不会工作,因为它需要一个函子返回一些东西。 – pmr

回答

0

这是一个使用手工算法的非并行实现。我相信有人更熟悉functional可以提出一个更优雅的解决方案。 transform的问题在于,我们不能将它用于返回void的函数,我不记得另一个需要两个范围并将它们应用于彼此的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; 
}