Reputation: 867
I have the following lambda expression:
auto pPerson = std::make_unique<Person>("Person");
auto personLambda = [=, persPointer = std::move(pPerson)](int x, int y) mutable
{
//do stuff
};
acceptLambda(myVector, personLambda);//compiler error
acceptLambda():
template<typename Func>
void acceptLambda(std::vector<int> myVector, Func f) {
//do stuff
}
error:
function "lambda []std::string (int c, int y) mutable->std::string<unnamed>(const lambda []std::string (int x, int y) mutable->std::string &)" (declared implicitly) cannot be referenced -- it is a deleted function
As outlined above, I am running into a compiler error telling me I cannot pass this lambda into the acceptLamba() function. I have other lambdas above that work just fine; when I pass personLambda in (which contains an std::move in the capture clause) everything breaks.
When I remove the move operation on the unique_ptr, everything works as expected. However, I want to move this unique_ptr into the lambda for use in a concurrent environment and avoid a dangling pointer situation.
Why does the std::move
operation cause this error? How does one remedy this issue?
Upvotes: 0
Views: 1092
Reputation: 16873
Let's start with a the error message:
function "lambda []std::string (int c, int y) mutable->std::string<unnamed>(const lambda []std::string (int x, int y) mutable->std::string &)" (declared implicitly) cannot be referenced -- it is a deleted function
That's a mouthful. It's more understandable if you recognize that lambda []std::string (int c, int y) mutable->std::string
is a name for the type of your lambda (apparently its return
statement causes the auto
to be deduced as std::string
). Let's call that type L
and see what the message looks like.
function "L(const L &)" (declared implicitly) cannot be referenced -- it is a deleted function
Your lambda's copy constructor is implicitly deleted. That should make sense since your lambda has captured a non-copyable value (the unique_ptr
). And yet, you try to make a copy when you pass personLambda
by value to acceptLambda
. This does not work.
The full error message probably has more information that could help point you to seeing why your lambda cannot be copied. After the error
line are probably some note
lines explaining that unique_ptr
cannot be copied. When using an IDE, such as Visual Studio, you might have to switch from the summary compiler output tab to the full compiler output tab to see this, though.
Option 1
You might be able to pass the lambda by reference. Might. Maybe you do need a copy in the larger scheme of things, but if you don't, then acceptLambda
could take its second argument by reference (and probably should take the first argument by const reference).
void acceptLambda(const std::vector<int> & myVector, Func & f)
// ^-- by reference
Option 2
You could get around being unable to copy your lambda the same way you got around being unable to copy your unique_ptr
. You could move it. Just be aware that personLambda
will not be usable after the call to acceptLambda
. (If this is a problem, you likely should be using a shared_ptr
instead of a unique_ptr
.)
acceptLambda(myVector, std::move(personLambda));
// ^^^^^^^^^^ ^
Upvotes: 2