1
votes

I'm trying to understand the implications of the lambda expression in the code snippet below.

The lambda expression captures variables by value rather than by reference otherwise the local variable message is destroyed when foo exits.

What I don't understand is the capture of m_impl. How is it captured by value if the copy ctor of Impl is deleted? Please can someone enlighten me?

void Foo::foo(std::shared_ptr<std::string> message)
{
    m_impl->m_thread.send([=] { m_impl->handleMessage(message); });
}

handleMessage is declared as:

void handleMessage(std::shared_ptr<std::string> message)

and m_impl as:

std::unique_ptr<Impl> m_impl;

Impl has its copy constructor and assignment operator deleted.

1
I'm not certain at all, but my guess is it would be moved instead of copied, so the original 'copy' of m_impl is invalid after creation of the lambda - dgel
it's this that is captured by value, not m_impl as you suspect. m_impl is accessed indirectly through that implicit this pointer - Piotr Skotnicki

1 Answers

7
votes

The things that can be captured are:

  • local variables, by value or reference;
  • in a class member function, the this pointer, by value.

Member variables are not captured, although capturing this effectively captures them by reference. By specifying a capture default, this will be captured if you refer to any class member within the lambda body, allowing access to that member.

Presumably, m_impl is a member variable, so that's what's happening here.