Say I want to create an exception object, but throw it a bit later. My use case is that the exception is generated in a thread, but I need to actually throw it from my main thread (because there's nobody to catch it in the child thread)
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;
}
For what it's worth, the compiler seems happy with this, but I can see that it's a resource leak at best. Is there a right way to do this?
CodePudding user response:
std::exception_ptr
is the C facility to store exceptions. It can usually avoid an extra allocation.
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);
}
And since it can store any type of exception, you can store anything that could be thrown in the thread by wrapping the lambda like:
std::thread myThread( [&ex]{
try {
// do things
} catch (...) {
ex = std::current_exception();
}
} );
Alternatively, you can use a 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;
}
Which won't leak since you don't dynamically allocate
CodePudding user response:
Here is one solution I found, but I liked the unique_ptr solution better. Writing it here for completeness:
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;
}