Asio lambda with unique_ptr capture

I am using asio standalone 1.10.6 and vs2015 rc.

vs2015 supports unique_ptr capture. So I wrote code similar to:

auto data = std::make_unique<std::string>("abc");
auto buffer = asio::buffer(data->c_str(), data->size());
asio::async_write(s, buffer, [data = std::move(data)](
  const asio::error_code& error, size_t byte_transferred) mutable {
  do_something(std::move(data), error, byte_transferred);
});

But when I compile the code, the compiler said:

error C2280: .... attempt to reference a remote function

As I understand it, it said that I was trying to copy lambda, and because lambda captures std::unique_ptr, so it is not amenable to copy.

Which bothers me, why asio wants to copy lambda but not move lambda.

What happened to my code? How to do it?

===========================

Full code:

void do_something(std::unique_ptr<std::string> data) { }

void compile_failed() {
  asio::io_service io_service;
  asio::ip::tcp::socket s(io_service);

  auto data = std::make_unique<std::string>("abc");
  auto buffer = asio::buffer(data->c_str(), data->size());

  asio::async_write(s, buffer, [data = std::move(data)](const asio::error_code& error,
    size_t byte_transferred) mutable {
    do_something(std::move(data));
  });
}

template<typename T > struct lambda_evil_wrap {
  mutable T ptr_;
  lambda_evil_wrap(T&& ptr) : ptr_(std::forward< T>(ptr)) {}
  lambda_evil_wrap(lambda_evil_wrap const& other) : ptr_(std::move(other.ptr_)) {}
  lambda_evil_wrap & operator=(lambda_evil_wrap& other) = delete;
};

void compile_success_but_very_danger() {
  asio::io_service io_service;
  asio::ip::tcp::socket s(io_service);

  auto data = std::make_unique<std::string>("abc");
  auto buffer = asio::buffer(data->c_str(), data->size());

  lambda_evil_wrap<std::unique_ptr<std::string>> wrapper(std::move(data));
  asio::async_write(s, buffer, [wrapper](const asio::error_code& error,
    size_t byte_transferred) mutable {
    do_something(std::move(wrapper.ptr_));
  });
}

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

, unique_ptr , , . lambda_evil_wrap:: lambda_evil_wrap (lambda_evil_wrap const & a) . , asio :

Handler handler2(handler);
handler(...); // Crash here
+4
1

, , CopyConstructible:

CopyConstructible (++ Std, 20.1.3).

Boost.Asio ++ 11 , , Boost.Asio , - :

[...] Boost.Asio , . Boost.Asio . , - .

, std::shared_ptr std::unique_ptr, lambda .

+5

All Articles