为什么我的c ++ lambda函数不能被捕获?

时间:2011-05-03 13:22:14

标签: c++ lambda c++11

说我有一个模板化的动作

template <class ArgT>
struct Action
{
    Action(::boost::function< void(ArgT) > func)
        : func_(func)
    {
    }

    void operator()(ArgT arg)
    {
        func_(arg);
    }

private:
        ::boost::function< void(ArgT) > func_;
};

我像这样使用Action:

class XCallbackInvoker : public CallbackInvoker< X >
{
public:
    XCallbackInvoker (Action< int > callback)
        : CallbackInvoker< X >(
            Action< ::boost::shared_ptr< X > >(
               [&callback](::boost::shared_ptr< X > x) -> void
               {
                   Action< int > callbackCopy = callback;
                   callbackCopy(x->errorCode());
               }))
    {
    }
};

编辑:CallbackInvoker已添加

template <class T>
class CallbackInvoker : public ICallbackInvoker
{
public:
    CallbackInvoker(Action< ::boost::shared_ptr< T > > callback)
        : callback_(callback)
    {
    }

    void invoke(::boost::shared_ptr< IBase > message)
    {
        callback_(::boost::static_pointer_cast< T >(message));
    }

private:
    Action< ::boost::shared_ptr< T > > callback_;
};

现在如果我不使用临时复制回调引用的值,它编译得很好,但是我收到运行时错误(我的回调丢失了)。如果我通过值传递我的lambda回调参数(即[=callback])并且不使用临时,我得到一个编译错误(我的表达式会丢失一些const-volatile限定符......)

为什么我不能通过值捕获lambda函数而不是使用临时函数?

1 个答案:

答案 0 :(得分:11)

如果您通过副本捕获,则默认情况下无法修改它,因为lambda的operator()被声明为const。您需要将mutable添加到lambda以允许修改捕获的变量:

XCallbackInvoker (Action< int > callback)
    : CallbackInvoker< X >(
        Action< ::boost::shared_ptr< X > >(
           [callback](::boost::shared_ptr< X > x) mutable -> void
           {
               callback(x->errorCode());
           }))
{
}