我试图了解异常如何在不同函数之间传播并返回到 C++ 中的主函数。我有一个小设置:
main.cpp:
int run () {
.
.
try {
testException(file);
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
测试.cpp
std::exception_ptr g_exceptionPtr = nullptr;
void testThread() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
.
.
}
void testException(const std::string &file) {
TestCSV csv(file);
try {
std::thread input(testThread);
csv.writeToCSV(file, a, b, c);
input.join();
} catch (const std::runtime_error &e) {
g_exceptionPtr = std::current_exception();
std::rethrow_exception(g_exceptionPtr);
}
}
在
test_csv.cpp
:
TestCSV::writeToCSV(const std::string &file, const std::string &a, const std::string &b, const std::string &c) {
.
.
std::ofstream outFile(file);
if (!outFile.is_open()) {
throw std::runtime_error("Unable to open file for writing.");
}
}
现在我想传播来自
writeToCSV
函数的错误并在 main.cpp
中处理它。但是,目前,此异常已在 test.cpp
中捕获,但不会重新抛出到 main.cpp
。
问题是什么以及如何解决?
P.S:以上代码只是一个示例,如果缺少任何信息,请告诉我
您在运行
writeToCSV()
的主线程上下文中调用 main()
,因此 writeToCSV()
引发且未被捕获的任何异常都将传播到 main()
。您不需要为此做任何额外的事情。而你的 std::thread
用法与此无关。
但是,由于您的问题是关于跨线程传播异常,因此您应该更改测试以将
writeToCSV()
移至 std::thread
。
std::current_exception
允许您捕获捕获的异常,以便您可以在 catch
之外访问它。对于您所问的问题,您需要在原始线程中捕获该异常,将其移至主线程,然后在对 std::rethrow_exception
进行 join
编辑后调用 std::thread
(如果分配了 exception_ptr
) ,例如:
void testThread(const std::string &file, std::exception_ptr &exceptionPtr) {
try {
TestCSV csv(file);
csv.writeToCSV(...);
} catch (const std::exception &e) {
exceptionPtr = std::current_exception();
}
}
void testException(const std::string &file) {
std::exception_ptr exceptionPtr = nullptr;
std::thread input(testThread, file, std::ref(exceptionPtr));
input.join();
if (exceptionPtr)
std::rethrow_exception(exceptionPtr);
}