Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't my c++ lambda function be captured?

Tags:

c++

c++11

lambda

Say I have a templated Action

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_;
};

I use Action like so :

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());
               }))
    {
    }
};

Edit: CallbackInvoker added

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_;
};

Now if I don't use a temporary to copy the value referenced by callback, it compiles fine but I get a runtime error (my callback is lost). If I pass my lambda the callback argument by value (that is [=callback]) and don't use the temporary, I get a compile error (my expression would lose some const-volatile qualifiers...)

Why can't I capture my lambda function by value instead of using a temporary?

like image 526
mister why Avatar asked Dec 22 '22 14:12

mister why


1 Answers

If you capture by copy then you cannot modify it by default, since the operator() of the lambda is declared const. You need to add mutable to your lambda to allow modifications of the captured variables:

XCallbackInvoker (Action< int > callback)
    : CallbackInvoker< X >(
        Action< ::boost::shared_ptr< X > >(
           [callback](::boost::shared_ptr< X > x) mutable -> void
           {
               callback(x->errorCode());
           }))
{
}
like image 149
Anthony Williams Avatar answered Dec 24 '22 05:12

Anthony Williams