4

Here is the code to demo the problem:

 #include <iostream>
 #include <memory>
 #include <functional>

 using namespace std;

 int main()
 {
     // lambda with a unique_ptr
     auto u = std::make_unique<int>(10);
     auto lambda = [u=std::move(u)]
     {
         cout << *u << endl;
     };

     // lambda itself is movable
     auto lambdaM = std::move(lambda);

     // lambda not able to move into a std::function - compiler trying to call the copy construtor, which is deleted
     std::function<void(void)> func(std::move(lambda));
     func();
 }

The code doesn't compile with:

g++-8 --std=c++2a -o move_lambda_to_function -g3 -rdynamic move_lambda_to_function.C

complaining about:

/usr/include/c++/8/bits/unique_ptr.h:394:7: note: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^~~~~~~~~~

It seems like std::function try to copy, rather than move the lambda object, any idea why it is not working with lambda has movable-only object?

Baiyan Huang
  • 6,463
  • 8
  • 45
  • 72
  • `std::function` [constructor](https://en.cppreference.com/w/cpp/utility/functional/function/function) takes its argument by value, which requires a copy. Why there isn't an overload taking rvale reference, I'm not sure. – Igor Tandetnik Dec 13 '18 at 04:22
  • 1
    https://stackoverflow.com/questions/16639131/can-stdfunction-be-move-constructed-from-rvalue-reference-to-a-temporary-funct looks like a dupe? – Jonathan Potter Dec 13 '18 at 04:24
  • 1
    I was going to answer but it was marked closed before I could complete it. In short `std::function` can move construct from lambda if and only if the capture - return clause of the lambda is itself copyable. Since you are using `std::unique_ptr` which has a deleted copy & assignment operators you can not construct move from a `unique_ptr`. If you take your existing code and replace `std::unique_ptr` with `std::shared_ptr` the code will work perfectly fine! – Francis Cugler Dec 13 '18 at 05:06
  • Thanks guys, seems like it is all about type erasure which need access to copy constructor: https://stackoverflow.com/questions/11768273/why-cant-c11-move-a-noncopyable-functor-to-a-stdfunction – Baiyan Huang Dec 13 '18 at 06:03
  • The semi regular wrapper of the range library could not be an implementation detail: http://eel.is/c++draft/range.semi.wrap – Oliv Dec 13 '18 at 12:04

0 Answers0