按值捕获std :: function

时间:2012-04-01 19:53:14

标签: c++ lambda crash

我使用以下代码:

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函数队列工作在另一个线程上异步完成(通过从上面调用group.run(lambda))。我遇到的问题是我在尝试调用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 个答案:

答案 0 :(得分:1)

在您的复制构造函数中使用std::ref意味着您保留对旧WorkData的{​​{1}}成员的引用,而不是副本。您希望Callback制作副本以避免访问冲突(可能是在释放后访问旧回调)。为了在Callback = other.Callback中保留对resProc的引用,您需要在std::function的调用中使用std::ref(resProc)