0

I'm trying to create a unique_ptr, capture it into lambda expression (by move semantics), then use it a callback parameter (as std::function).

#include <functional>
#include <memory>
    
// This function is an asynchronous function, and func is actually a callback.
void Func(std::function<void(void)> func) { func(); }
    
int main() {
    auto ptr = std::make_unique<size_t>();
    auto cb = [p = std::move(ptr)]() {};
    std::function<void(void)> tmp_cb = std::move(cb);
    Func(std::move(tmp_cb));
}

The compilation error message looks like (clang 13.0.0)

test.cc:9:37: note: in instantiation of function template specialization 'std::function<void ()>::function<(lambda at test.cc:8:12), void>' requested here
        std::function<void(void)> tmp_cb = std::move(cb);
                                               ^
test.cc:8:13: note: copy constructor of '' is implicitly deleted because field '' has a deleted copy constructor
        auto cb = [p = std::move(ptr)]() {};
                       ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/memory:1584:3: note: copy constructor is implicitly deleted because 'unique_ptr<unsigned long>' has a user-declared move constructor
  unique_ptr(unique_ptr&& __u) _NOEXCEPT

My guess is: though I use std::move, I'm actually converting a lambda object (a structure underlying) to a std::function, thus leading to an implicit copy.

My questions are:

  1. Is my analysis correct? If not, what's the reason for this error?

  2. Do we have a way to use unique pointer (or any other un-copiable type) in lambda, and pass it into function as a param (as std::function)?

Tinyden
  • 524
  • 4
  • 13
  • The line in your error message does not appear in your code. – JaMiT Apr 16 '22 at 01:51
  • *"copy constructor of '' is implicitly deleted because field '' has"* -- two key pieces of information (the type with the deleted copy constructor and the problematic field) are missing from this error message. – JaMiT Apr 16 '22 at 01:59
  • 2
    In a nutshell - the error is because `std::function` requires the target to be [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible), but your lambda is not copyable since it holds a captured `unique_ptr` (which is a non-copyable type) – Remy Lebeau Apr 16 '22 at 02:18
  • @JaMiT Ah yes, updated – Tinyden Apr 16 '22 at 03:20
  • @RemyLebeau Understand! – Tinyden Apr 16 '22 at 03:20

0 Answers0