C++20 引入了协程(coroutines),它们允许编写更简洁的异步代码。在 C++ 中,协程使用 co_await
, co_yield
, 和 co_return
关键字来定义。处理协程中的异常与处理普通的 C++ 函数中的异常类似,但有一些不同之处。
当在协程中使用 co_await
时,可能会遇到 std::exception_ptr
类型的异常。这是因为协程可以抛出异常,而这些异常需要在协程完成或被销毁时处理。为了处理这些异常,你需要使用 std::experimental::coroutine_traits
或 std::coroutine_traits<T>
的特化版本来定义异常类型。
以下是一个简单的示例,展示了如何在 C++ 协程中处理异常:
#include <iostream>
#include <exception>
#include <coroutine>
#include <experimental/coroutine>
struct Task {
struct promise_type {
Task get_return_object() {
return {};
}
std::experimental::suspend_never initial_suspend() {
return {};
}
std::experimental::suspend_never final_suspend() noexcept {
return {};
}
void return_void() {}
void unhandled_exception() {
std::cout << "Unhandled exception in coroutine" << std::endl;
}
};
};
Task asyncTask() {
try {
co_await std::suspend_never{};
throw std::runtime_error("An error occurred in coroutine");
} catch (const std::exception& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
}
int main() {
asyncTask();
return 0;
}
在这个示例中,我们定义了一个简单的协程 asyncTask
,它在协程体内抛出一个异常。我们使用 try-catch
语句捕获异常并处理它。注意,我们使用了 std::experimental::suspend_never
作为挂起类型,以便在协程体内立即抛出异常。在实际应用中,你可能需要根据你的需求选择合适的挂起类型。