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.
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.