Why "then" continuation cannot accept mutable lambda?

Sep 20, 2015 at 4:53 PM
Edited Sep 20, 2015 at 4:54 PM
I would like to use a lambda in "then" continuation. But it should be mutable lambda since it captures by move unique_ptr and then does something with it. this would not compile with "attempting to use deleted function" error, guess it tries to copy something.
Consider following code
class noncopyable {
public:
  noncopyable(){};
  noncopyable(const noncopyable &) = delete;
  noncopyable &operator=(const noncopyable &) = delete;
  noncopyable(noncopyable &&) = default;
  noncopyable &operator=(noncopyable &&) = default;

public:
  int a = 0;
  double b = 0.0;
};

class foo {
public:
    void bar(std::unique_ptr<noncopyable>&& arg)
    {
        m_nc = std::move(arg);
    }
    std::unique_ptr<noncopyable> m_nc;
};

 auto uptr = std::make_unique<noncopyable>();
  auto lambda = [ptr{std::move(uptr)}]() mutable {
      std::cout << ptr->a << " " << ptr->b << std::endl;
      foo f;
      f.bar(std::move(ptr));
  };
  lambda(); 
The above works with no problem, of course
But once we place this lambda in "then" which is const and receives const ref argument it tries to copy something (which is not really clear, what and why)
pplx::task<int>([]() {return 42; }).then([ptr{std::move(uptr)}](pplx::task<int> data) mutable {
      auto someData = data.get();
      std::cout << ptr->a << " " << ptr->b << std::endl;
      foo f;
      f.bar(std::move(ptr));
  });
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\ppltasks.h(3146): error C2280: 'main::<lambda_d5a12492736c0caad4bc5a6fcf62b912>::<lambda_d5a12492736c0caad4bc5a6fcf62b912>(const main::<lambda_d5a12492736c0caad4bc5a6fcf62b912> &)': attempting to reference a deleted function
so, my question is what and why it copies and how do I work around this issue
Sep 21, 2015 at 5:16 AM
I think I got the problem the _ContinuationTaskHandle copies the _Func argument (the lambda actually) into its member _M_function, thats why it complains about referencing deleted function, obviously it is because the unique_ptr which cannot be copied. I guess adding _ContinuationTaskHandle constructor which gets _Func as r-value and moves it into the member variable could solve this problem, right?
Sep 21, 2015 at 9:33 PM
Yes, I think performing a move here should be safe. I've opened an issue to track this: https://casablanca.codeplex.com/workitem/418.

Thanks for finding this issue.