2012-04-01 63 views
2

我使用下面的代碼:(從上面通過調用group.run(拉姆達))捕獲的std ::功能通過價值

struct WorkData 
{ 
    std::string name; 
    std::function<void(std::string)> Callback; 

    WorkData(){}; 
    WorkData(const WorkData& other) 
    { 
     name = other.name; 
     Callback = std::ref(other.Callback); 
    } 
}; 

WorkData data; // this is the data to pass to queue_task() function bellow 
data.Callback = std::bind(&ResultProcessor::Handler, resProc, std::placeholders::_1); 

template <typename Functor> 
void queue_task(Functor& fn, WorkData& workData) 
{ 
    group.run([&fn, workData](){ 
      workData.Callback("resultComming"); // runtime ERROR- access violation 
    }); 
} 

queue_task功能隊列的工作被另一個線程異步完成。我遇到的問題是在嘗試調用workData.Callback()時遇到訪問衝突。

我在group.run()中製作workData副本的原因是因爲我想通過值捕獲workData,以便當group.run()lambda執行時它具有queue_task()的狀態副本調用。我預計workData.Callback()將執行的對象的實例傳遞路線:

data.Callback = std::bind(&ResultProcessor::Handler, resProc, std::placeholders::_1); 

編輯:從上面resProc是活的(不破壞)時死機線被稱爲

回答

1

使用std::ref在您的拷貝構造函數中意味着您保留對舊的WorkDataCallback成員的引用,而不是副本。您希望Callback = other.Callback進行復制以避免訪問衝突(可能是在釋放後訪問舊回調)。爲了在std::function中保留對resProc的引用,您需要在std::bind的調用中使用std::ref(resProc)

+0

我在我的問題中編輯了編輯。我使用std :: ref,否則我最終會對ResultProcessor的另一個實例調用workData.Callback(「resultComming」) – Ghita 2012-04-01 19:59:39

+0

在這種情況下,您需要在ResultProcessor中使用'std :: ref',而不是函數對象本身。也就是說,在你的最後一個代碼塊中,你應該有'std :: ref(resProc)',然後在你的拷貝構造函數中使用'std :: function'的一個真實副本。 – 2012-04-01 20:13:44

+0

ResultProcessor實例與std :: function 一起傳輸,作爲queue_task()中的WorkData的一部分接口 – Ghita 2012-04-01 20:16:20