asio::experimental::use_promise要求结果类型可默认构造的编译问题
关于boost::asio中
asio::experimental::use_promise导致编译错误的问题 我用boost::asio实现了一个实验性TCP代理,将代码中所有asio::use_awaitable替换为asio::experimental::use_promise后,以下代码无法编译:
asio::awaitable<void> runProxy(tcp::endpoint listen_endpoint, ssl::context client_ctx, const std::string& target_host, const std::string& target_port) { // 获取 acceptor 的执行器 auto exec = co_await asio::this_coro::executor; tcp::acceptor acceptor(exec, listen_endpoint); tcp::socket sock = co_await acceptor.async_accept(asio::experimental::use_promise); // .. }
MSVC给出的错误信息:
error C2512: 'boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::any_io_executor>': no appropriate default constructor available
错误的触发点在boost_1_89_0\include\boost-1_89\boost\asio\experimental\impl\promise.hpp中的这段代码:
template<typename... T_> void cancel_impl_(boost::system::error_code*, T_*...) { complete(boost::asio::error::operation_aborted, T_{}...); }
问题分析
asio::experimental::use_promise的取消逻辑设计要求:当操作被取消时,需要通过默认构造T_{}...生成结果类型的实例,再传递给complete函数。但tcp::socket(即basic_stream_socket)并没有提供默认构造函数,因此编译时触发了C2512错误。
而asio::use_awaitable的取消逻辑是通过协程的异常机制直接传递取消错误,不需要构造结果对象,所以不会遇到这个问题。
结论
这属于asio::experimental::use_promise的设计局限,而非严格意义上的实现疏漏——该实验性特性的设计前提是结果类型支持默认构造。如果要在不可默认构造的类型(如socket)上使用use_promise,要么等待官方优化该特性的取消逻辑,要么自行封装适配层,避免在取消时构造默认对象。
内容的提问来源于stack exchange,提问作者Dmitriano
相关产品推荐
相关产品推荐

