std::future::get()会抛出已存储的异常,wait()不会;get()是消费型操作,调用后future失效,只能调用一次,而wait()可重复调用且不改变状态。

std::future::get() 会抛出已存储的异常,wait() 不会
当异步任务执行中抛出异常,std::promise(或 std::packaged_task)会把异常保存在关联的 std::future 内部状态中。get() 在首次调用时——无论是否已就绪——都会尝试取值:若任务成功则返回结果;若已存储异常,则直接以 std::rethrow_exception() 方式抛出该异常。而 wait() 完全不访问结果或异常,它只阻塞直到状态变为 ready,之后仍需调用 get() 或检查 valid() 等才能感知异常。
多次调用 get() 是未定义行为,wait() 可安全重复调用
get() 是“消费型”操作:一旦调用,内部共享状态被销毁(future 变为 not valid),再次调用会触发 std::future_error,错误码为 std::future_errc::no_state。而 wait() 是只读操作,不改变状态,可在任意次调用,包括在 get() 之后(只要 future 仍 valid)。
- 若你只关心任务完成时间、不关心结果或异常,用
wait() - 若你需要结果或必须处理可能的异常,必须用
get(),且只能调用一次 - 不能靠
wait()来“避开异常”——它只是延迟了异常暴露时机,get()仍会抛
异常类型和栈信息在 get() 中原样传递
get() 抛出的异常是原始异常对象的拷贝(通过 std::exception_ptr 重建),包括其动态类型和 what() 内容。但注意:原始栈回溯通常丢失,除非你在 promise 端手动捕获并封装上下文。
#include#include #include int main() { auto fut = std::async(std::launch::async, []{ throw std::runtime_error("task failed"); return 42; }); fut.wait(); // 阻塞完成,无异常 try { auto val = fut.get(); // 此处才抛出 runtime_error } catch (const std::runtime_error& e) { std::cout << e.what(); // 输出 "task failed" } }
wait_for() / wait_until() 和 get() 的异常语义一致
所有以 wait 开头的成员函数(wait()、wait_for()、wait_until())都不抛异常,也不访问结果;只有 get() 承担异常传播职责。这意味着:即使 wait_for() 返回 std::future_status::timeout,后续调用 get() 仍可能立即抛异常(如果任务最终失败)。
立即学习“C++免费学习笔记(深入)”;
异常处理的关键不在“等不等”,而在“取不取”。get() 是唯一能触发异常重抛的入口,也是唯一需要 try-catch 包裹的地方;wait() 只是同步点,不参与错误传递逻辑。











