如何保存异常并稍后抛出
How to save an exception and throw it later
说我想创建一个异常对象,但稍后抛出。我的用例是异常是在一个线程中产生的,但我实际上需要从我的主线程中抛出它(因为没有人在子线程中捕获它)
using namespace std;
runtime_error *ex = nullptr;
thread myThread( [&ex]{
if (something_went_wrong) {
ex = new runtime_error("Something went wrong");
return;
}
} );
myThread.join();
if (ex != nullptr) {
throw *ex;
}
就其价值而言,编译器似乎对此很满意,但我可以看出它充其量只是资源泄漏。有正确的方法吗?
这是我找到的一种解决方案,但我更喜欢 unique_ptr 解决方案。为了完整起见写在这里:
using namespace std;
runtime_error *ex = nullptr;
thread myThread( [&ex]{
if (something_went_wrong) {
ex = new runtime_error("Something went wrong");
return;
}
} );
myThread.join();
if (ex != nullptr) {
runtime_error e2 = *ex;
delete ex;
throw e2;
}
std::exception_ptr
是用于存储异常的 C++ 工具。它通常可以避免额外的分配。
std::exception_ptr ex = nullptr;
std::thread myThread( [&ex]{
if (something_went_wrong) {
ex = std::make_exception_ptr(std::runtime_error("Something went wrong"));
return;
}
} );
myThread.join();
if (ex != nullptr) {
std::rethrow_exception(ex);
}
并且由于它可以存储任何类型的异常,因此您可以通过像这样包装 lambda 来存储可能在线程中抛出的任何内容:
std::thread myThread( [&ex]{
try {
// do things
} catch (...) {
ex = std::current_exception();
}
} );
或者,您可以使用 std::optional<std::runtime_error>
std::optional<std::runtime_error> ex;
std::thread myThread( [&ex]{
if (something_went_wrong) {
ex.emplace("Something went wrong");
return;
}
} );
myThread.join();
if (ex) {
throw *ex;
}
不会泄漏,因为您不动态分配
说我想创建一个异常对象,但稍后抛出。我的用例是异常是在一个线程中产生的,但我实际上需要从我的主线程中抛出它(因为没有人在子线程中捕获它)
using namespace std;
runtime_error *ex = nullptr;
thread myThread( [&ex]{
if (something_went_wrong) {
ex = new runtime_error("Something went wrong");
return;
}
} );
myThread.join();
if (ex != nullptr) {
throw *ex;
}
就其价值而言,编译器似乎对此很满意,但我可以看出它充其量只是资源泄漏。有正确的方法吗?
这是我找到的一种解决方案,但我更喜欢 unique_ptr 解决方案。为了完整起见写在这里:
using namespace std;
runtime_error *ex = nullptr;
thread myThread( [&ex]{
if (something_went_wrong) {
ex = new runtime_error("Something went wrong");
return;
}
} );
myThread.join();
if (ex != nullptr) {
runtime_error e2 = *ex;
delete ex;
throw e2;
}
std::exception_ptr
是用于存储异常的 C++ 工具。它通常可以避免额外的分配。
std::exception_ptr ex = nullptr;
std::thread myThread( [&ex]{
if (something_went_wrong) {
ex = std::make_exception_ptr(std::runtime_error("Something went wrong"));
return;
}
} );
myThread.join();
if (ex != nullptr) {
std::rethrow_exception(ex);
}
并且由于它可以存储任何类型的异常,因此您可以通过像这样包装 lambda 来存储可能在线程中抛出的任何内容:
std::thread myThread( [&ex]{
try {
// do things
} catch (...) {
ex = std::current_exception();
}
} );
或者,您可以使用 std::optional<std::runtime_error>
std::optional<std::runtime_error> ex;
std::thread myThread( [&ex]{
if (something_went_wrong) {
ex.emplace("Something went wrong");
return;
}
} );
myThread.join();
if (ex) {
throw *ex;
}
不会泄漏,因为您不动态分配