I am attempting to come up with a solution for move-capturing a std::unique_ptr into a lambda, creating an std::function<void()> from that lambda, moving that function into a queue, then later moving the function out of the queue to execute it.
Here is my test code:
#include <functional>
#include <iostream>
#include <memory>
using fn_t = std::function<void()>;
struct Foo {
Foo(int a, int b) : a(a), b(b) {
std::cout << "Foo::Foo()" << std::endl;
}
~Foo() {
std::cout << "Foo::~Foo()" << std::endl;
}
int a;
int b;
};
static fn_t fnQueue;
void queue(fn_t fn) {
fnQueue = std::move(fn);
}
void dequeue() {
fnQueue();
fnQueue = fn_t();
}
template <typename FN>
inline void invoke(FN&& fn) {
queue(std::forward<FN>(fn));
dequeue();
}
int main() {
std::unique_ptr<Foo> ptr(new Foo{10, 11});
invoke([ptr = std::move(ptr)](){
std::cout << "a=" << ptr->a << ", b=" << ptr->b << std::endl;
});
return 0;
}
Which results in the following compile-time error:
In file included from C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/functional:59,
from lambda_unique_ptr.cpp:1:
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/std_function.h: In instantiation of 'static void std::_Function_base::_Base_manager<_Functor>::_M_clone(std::_Any_data&, const std::_Any_data&, std::false_type) [with _Functor = main()::<lambda()>; std::false_type = std::integral_constant<bool, false>]':
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/std_function.h:208:16: required from 'static bool std::_Function_base::_Base_manager<_Functor>::_M_manager(std::_Any_data&, const std::_Any_data&, std::_Manager_operation) [with _Functor = main()::<lambda()>]'
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/std_function.h:676:19: required from 'std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = main()::<lambda()>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = void; _ArgTypes = {}]'
lambda_unique_ptr.cpp:41:6: required from here
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/std_function.h:173:6: error: use of deleted function 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)'
new _Functor(*__source._M_access<_Functor*>());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lambda_unique_ptr.cpp:39:38: note: 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)' is implicitly deleted because the default definition would be ill-formed:
invoke(fn_t([ptr = std::move(ptr)](){
^
lambda_unique_ptr.cpp:39:38: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Foo; _Dp = std::default_delete<Foo>]'
In file included from C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/memory:80,
from lambda_unique_ptr.cpp:3:
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:394:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
Any ideas how to make this work?