I am capturing a unique_ptr in a lambda expression this way:
auto str = make_unique(\"my string\");
auto lambda = [ capturedStr = std::move(str)
auto lambda = [ capturedStr = std::move(str) ] {
cout << *capturedStr.get() << endl;
auto str2 = std::move(capturedStr); // <--- Not working, why?
};
To give more detail the compiler is effectively making this transformation:
class NameUpToCompiler
{
unique_ptr<string> capturedStr; // initialized from move assignment in lambda capture expression
void operator()() const
{
cout << *capturedStr.get() << endl;
auto str2 = std::move(capturedStr); // move will alter member 'captureStr' but can't because of const member function.
}
}
The use of mutable on the lambda will remove the const from the operator() member function therefore allowing the members to be altered.
To make the advice more explicit: add mutable
: http://coliru.stacked-crooked.com/a/a19897451b82cbbb
#include <memory>
int main()
{
std::unique_ptr<int> pi(new int(42));
auto ll = [ capturedInt = std::move(pi) ] () mutable { };
}
The operator ()
of a lambda is const
by default, and you can't move from a const
object.
Declare it mutable
if you want to modify the captured variables.
auto lambda = [ capturedStr = std::move(str) ] () mutable {
// ^^^^^^^^^^
cout << *capturedStr.get() << endl;
auto str2 = std::move(capturedStr);
};