2012-04-01 64 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