You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 03:07:22