std::future不处理返回码,仅传递返回值或异常;返回码需由函数逻辑定义为返回类型的一部分,如int、std::error_code、std::expected或自定义枚举。

std::future 本身不处理“返回码”——它只传递异步任务的返回值或异常,所谓“返回码”必须由你自己的函数逻辑定义并作为返回类型的一部分显式传出。
std::future.get() 拿到的是什么类型,就决定了你能拿到什么“码”
如果你的异步函数返回 int,那 fut.get() 就返回一个 int;如果返回 std::error_code、std::expected<int std::error_code></int> 或自定义枚举(如 enum class ResultCode { OK = 0, TIMEOUT = -1, NETWORK_ERR = -2 };),那你就得按这个类型去接收和判断。
- 别指望
std::future自动解析“成功/失败”语义——它只负责搬运,不负责解释 - 返回
void的异步任务,future<void></void>的get()不返回任何值,只能用wait()或wait_for()判断是否完成 - 若需同时传值 + 错误码,推荐用
std::expected<t e></t>(C++23)或std::pair<t std::error_code></t>,避免靠异常承载业务错误
异常不是“返回码”,但常被误当返回码用
当异步函数抛出异常(如 throw std::system_error(errc::connection_refused)),std::future::get() 会原样 rethrow。这不是返回码,而是控制流中断——调用方必须用 try/catch 捕获,否则程序终止。
- 业务逻辑错误(如 HTTP 404、鉴权失败)不该靠异常传递,应走返回值路径;系统级故障(内存分配失败、线程创建失败)才适合用异常
- 在
std::async启动的 lambda 里没写try/catch,又没在get()外包try/catch,就会 crash -
std::future_status::deferred不是错误,只是说明任务还没执行;wait_for()返回它时,get()才真正触发执行
wait_for() 超时后,future 仍有效,但你得自己定义“超时码”
wait_for() 返回 std::future_status::timeout,这仅表示“此刻还没就绪”,不代表任务失败。后续仍可 wait_for() 重试,或直接 get() 阻塞等待——但你要把“超时”映射成业务可理解的返回码,得自己编码实现。
- 例如:定义
enum class OpResult { SUCCESS, TIMEOUT, FAILED };,异步函数返回该枚举,而非依赖wait_for()的状态 - 别在循环里反复
wait_for(1ms)查状态——CPU 空转,且无法区分“真超时”和“暂时未就绪” - 若底层调用本身有超时(如
curl_easy_perform),应在异步函数内部处理并返回对应码,而不是靠外层wait_for()
std::shared_future 支持多处读取,但“返回码”语义必须一致
当你需要多个线程检查同一异步结果(比如主线程判断成功与否,日志线程记录返回码),必须用 std::shared_future。但要注意:
-
share()只能调一次,且必须在原始std::future调用get()或移动前完成 - 所有
shared_future::get()调用看到的是同一个返回值或异常——不能让一个线程拿到OK,另一个拿到TIMEOUT - 若返回类型是
std::shared_ptr或大对象,多次get()会触发多次拷贝,性能敏感场景需注意
最易忽略的一点:std::future 的生命周期管理直接影响你能否安全拿到“返回码”。临时对象导致 std::launch::deferred 任务永不执行,或者析构时意外阻塞,都会让你根本等不到任何码——先保命,再取值。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











