I want to pass a raw pointer inside lambda, but I don't want it to be leaked, if the lambda isn't invoked. It looks like this:
void Clean(std::unique_ptr<int>&& list);
void f(int* list) {
thread_pool.Push([list = std::unique_ptr<int>(list) ] {
Clean(std::move(list)); // <-- here is an error.
});
}
I get an error in Clang 3.7.0:
error: binding of reference to type 'unique_ptr<[2 * ...]>' to a value of type 'unique_ptr<[2 * ...]>' drops qualifiers
But I don't see any qualifiers at the first place, especially dropped.
Also, I found similar report on the mailing list, but without answer.
How should I modify my code, so it gets compiled and works as expected by semantics?
You need to make the inner lambda
mutable
:operator()
on lambdas isconst
by default, so you cannot modify its members in that call. As such, the internallist
behaves as if it were aconst std::unique_ptr<int>
. When you do themove
cast, it gets converted to aconst std::unique_ptr<int>&&
. That's why you're getting the compile error about dropping qualifiers: you're trying to convert a const rvalue reference to a non-const rvalue reference. The error may not be as helpful as it could be, but it all boils down to: you can'tmove
aconst unique_ptr
.mutable
fixes that -operator()
is no longerconst
, so that issue no longer applies.Note: if your
Clean()
took aunique_ptr<int>
instead of aunique_ptr<int>&&
, which makes more sense (as it's a more explicit, deterministic sink), then the error would have been a lot more obvious: