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

asio::async_compose编译错误:err被推导为void类型的问题

编译错误分析与解决

你遇到的编译错误deduced type 'void' for 'err' is incomplete,核心原因是Boost.Asio的co_await在处理签名为void(sys::error_code)的异步操作时,默认行为是将错误码包装为sys::system_error异常抛出,而非直接返回错误码。此时co_await conn.async_connect()的返回类型是void,自然无法赋值给变量err,从而触发编译错误。

解决方案1:通过asio::as_tuple获取错误码

使用asio::as_tuple(asio::use_awaitable)作为完成令牌,让异步操作的awaitable返回包含错误码的元组,就能直接获取错误码而不触发异常:

asio::awaitable<void> co_main(std::string_view host, std::string_view port)
{
    auto executor = co_await asio::this_coro::executor;

    auto conn = tcp_connection(host, port, executor);

    // 使用as_tuple获取错误码
    auto [err] = co_await conn.async_connect(asio::as_tuple(asio::use_awaitable));

    if (err) {
        debugln("连接失败: {}", err.message());
    } else {
        debugln("连接成功");
    }

    co_return;
}

解决方案2:捕获异常处理错误

保持原调用方式,通过try-catch捕获操作失败时抛出的sys::system_error异常:

asio::awaitable<void> co_main(std::string_view host, std::string_view port)
{
    auto executor = co_await asio::this_coro::executor;

    auto conn = tcp_connection(host, port, executor);

    try {
        co_await conn.async_connect();
        debugln("连接成功");
    } catch (const sys::system_error& e) {
        debugln("连接失败: {}", e.what());
    }

    co_return;
}

补充说明

你的async_connect函数定义的完成签名是void(sys::error_code),符合Asio异步操作的错误码优先风格。但在协程中使用co_await时,Asio会根据传入的完成令牌决定行为:

  • 默认使用asio::use_awaitable时,错误会被包装成异常抛出,返回值为void
  • 使用asio::as_tuple(asio::use_awaitable)时,错误码会被包含在返回的元组中,不会抛出异常

内容的提问来源于stack exchange,提问作者sheldon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 20:13:09