Я использую asio standalone 1.10.6 и vs2015 rc.asio lambda with unique_ptr capture
Поддержка vs2015 unique_ptr. Так что я написал некоторый код выглядит следующим образом:
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);
});
Но когда я компиляции кода, компилятор сказал:
ошибка C2280: .... пытается ссылаться на удаленную функцию
Как я понимаю, он сказал, что я пытаюсь скопировать лямбда, и потому, что лямбда захвата std::unique_ptr
, так что это noncopyable.
Что меня пугает, почему асио хочет скопировать лямбду, но не переместить лямбду.
Что случилось с моим кодом? Как обходиться?
=========================
Полный код:
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
'std :: ref (лямбда)'? – Jarod42
Вы уверены, что это проблема? Компилятор говорит что-нибудь еще? Всегда включайте полный и неотредактированный журнал ошибок в вопросе. –
Конечно, std :: ref (лямбда) может сделать компилятор счастливым. Но код неправильный. Когда функция вернется, данные будут освобождены и сбой в do_something. – alpha