gpt4 book ai didi

c++ - 具有 unique_ptr 捕获的 asio lambda

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:19:32 25 4
gpt4 key购买 nike

我正在使用 asio standalone 1.10.6 和 vs2015 rc。

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);
});

但是当我编译代码时,编译器说:

error C2280: .... attempting to reference a deleted function

据我了解,它说我尝试复制 lambda,并且因为 lambda 捕获 std::unique_ptr,所以它不可复制

让我困惑的是为什么asio要复制lambda而不是移动lambda。

我的代码有什么问题?如何解决?

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

完整代码为:

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

最佳答案

原代码的错误是handler不满足Handler type requirement因为它不是CopyConstructible:

A handler must meet the requirements of CopyConstructible types (C++ Std, 20.1.3).

正如 Boost.Asio 对 movable handlers 的 C++11 支持中所述,在可能的情况下,Boost.Asio 将更喜欢移动构造函数而不是复制构造函数,但处理程序仍必须是可复制构造的:

[...] Boost.Asio's implementation will use a handler's move constructor in preference to its copy constructor. In certain circumstances, Boost.Asio may be able to eliminate all calls to a handler's copy constructor. However, handler types are still required to be copy constructible.

要解决此问题,可以考虑使用 std::shared_ptr 而不是 std::unique_ptr,从而使 lambda 可复制构造。

关于c++ - 具有 unique_ptr 捕获的 asio lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30779806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com