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
相关产品推荐
相关产品推荐

