Your only real option is to invert the logic:
template<typename F, typename... Args>
auto convert_exceptions(F &&f, Args... &&args)
-> decltype(f(std::forward<Args>(args)...)) {
try {
return f(std::forward<Args>(args)...));
} catch (std::exception const e) { // StdLib exceptions
std::throw_with_nested(magic_exception{...});
} catch (CException* pEx) { // MFC exceptions
std::throw_with_nested(magic_exception{...});
} catch (CORBA::Exception const& e) { // CORBA exceptions
std::throw_with_nested(magic_exception{...});
}
}
You can now write:
try {
convert_exceptions([&]() {
// ...
});
} catch (const magic_exception &e) {
// ...
}