2011-12-07 12 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; 
}