Capturing perfectly-forwarded variable in lambda

Vittorio Romeo picture Vittorio Romeo · Nov 9, 2014 · Viewed 13.1k times · Source
template<typename T> void doSomething(T&& mStuff)
{
    auto lambda([&mStuff]{ doStuff(std::forward<T>(mStuff)); });
    lambda();
}

Is it correct to capture the perfectly-forwarded mStuff variable with the &mStuff syntax?

Or is there a specific capture syntax for perfectly-forwarded variables?

EDIT: What if the perfectly-forwarded variable is a parameter pack?

Answer

Columbo picture Columbo · Nov 9, 2014

Is it correct to capture the perfectly-forwarded mStuff variable with the &mStuff syntax?

Yes, assuming that you don't use this lambda outside doSomething. Your code captures mStuff per reference and will correctly forward it inside the lambda.

For mStuff being a parameter pack it suffices to use a simple-capture with a pack-expansion:

template <typename... T> void doSomething(T&&... mStuff)
{
    auto lambda = [&mStuff...]{ doStuff(std::forward<T>(mStuff)...); };
}

The lambda captures every element of mStuff per reference. The closure-object saves an lvalue reference for to each argument, regardless of its value category. Perfect forwarding still works; In fact, there isn't even a difference because named rvalue references would be lvalues anyway.