Search code examples
c++c++11c++14

Can I declare a variable inside a lambda capture clause?


I want to submit a handle but I only want it to be executed if a shared pointer is still valid:

// elsewhere in the class:
std::shared_ptr<int> node;

// later on:
const std::weak_ptr<int> slave(node); // can I do this in the capture clause somehow?
const auto hook = [=]()
{
  if (!slave.expired())
    //do something
  else
    // do nothing; the class has been destroyed!
};

someService.Submit(hook); // this will be called later, and we don't know whether the class will still be alive

Can I declare slave within the capture clause of the lambda? Something like const auto hook = [std::weak_ptr<int> slave = node,=]().... but unfortunately this doesn't work. I would like to avoid declaring the variable and then copying it (not for performance reasons; I just think it would be clearer and neater if I could create whatever the lambda needs without polluting the enclosing scope).


Solution

  • You can do this using generalized lambda captures in C++14:

    const auto hook = [=, slave = std::weak_ptr<int>(node)]()
    {
        ...
    };
    

    Here's a live example. Note that since there are no parameters or explicit return type, the empty parameter list (()) can be left out.

    As pointed out in the other answer, you can add mutable if you need to modify the captures:

    const auto hook = [=, slave = std::weak_ptr<int>(node)]() mutable { ... }