Search code examples
c++11lambdastdthread

'&' or '=' in lambda capture expression?


I'm trying to understand the implications of capturing variables by reference or by value in the following example use of a lambda expression.

/** Encapsulates the private implementation details of Thread. */
struct Thread::Impl
{
public:
    Impl() : m_queue(), m_thread()
    {
    }

private:
    Impl(const Impl&);
    const Impl& operator=(const Impl&);

    void run()
    {
        // do some work
    }

    std::unique_ptr<std::thread> m_thread;

    friend class Thread;
};

Thread::Thread() : m_impl(new Impl())
{
    // start the thread

    // ************************************
    // '=' or '&' in the the capture block?
    // ************************************
    m_impl->m_thread = std::unique_ptr<std::thread>(new std::thread( [&]{ m_impl->run(); } ));
}

Regardless of whether I use & or = in the capture block the above code works OK. So which should I use?

If I use [&], m_impl is captured by reference, right?

If I use [=] m_impl is captured by value, right? But I don't understand why it compiles. What is it making a copy of? The copy ctor for Impl is disabled.


Solution

  • If I use [&], m_impl is captured by reference, right? If I use [=] m_impl is captured by value, right?

    Neither of those is true. m_impl isn't captured at all. In both cases, the this is captured. But since the thread is a member variable of the object whose this pointer your capturing, this (ha!) is safe.

    Use whichever you prefer. Or [this], if you want to be more explicit.