在我的每个主要function中,我想捕捉某些类别的exception并将其转换为退出代码。
是否有一个更优雅的解决scheme,比开始和结束每个主要function的macros将粘贴隐含的try {} catch
我想要的?
我可以通过std::set_terminate
function实现吗?
例:
int main(){ try { //<- insert this /* the business logic goes here */ //-> and insert this } catch(const Someclass1& e){ return 2; } catch(const Someclass2& e){ return 3; } //... catch(...){ return 1; } }
一个干净的方式涉及到使用翻译功能与您的所有异常样板,返回相应的异常退出值。
template <typename Callable> int call_and_translate_for_boundary(Callable&& func) try { func(); return 0; } catch(const Someclass1& e){ return 2; } catch(const Someclass2& e){ return 3; } //... catch(...){ return 1; }
在你自己的代码中,你只关心用lambda封装你的业务逻辑,并将其传递给翻译函数,以便它可以捕获和翻译。
int main() { return call_and_translate_for_boundary([&]{ //business logic here }); }
我想你可以用宏来做一些事情。 就是这样:
#define MY_MAIN int main(int argc, char** argv) try // <- yes, try here #define MY_CATCH catch (const Someclass1& e){ return 1; } \ catch (const Someclass2& e){ return 1; } \ ... \ catch (...) { return -1; } MY_MAIN { // usual business... return 0; } MY_CATCH
这个想法是让宏写一个“围绕”主函数体,这是合法的。
int main() try { throw 1; } catch (int i) { return 0; }
活着的小例子
我通常这样做:
int main2(); int main() try { return main2(); } catch(std::exception &e) { // some display... }
当然,你可以有更多的捕鱼人员。
如果你需要在多个入口点放置相同的catch处理程序列表,那将是一个不同的问题。 解决方案有catch(...) { foo(); }
catch(...) { foo(); }
,其中foo()
函数try { throw; }
接着是所有的catch处理程序。
我怀疑如此。 在终止被调用的时候,你已经失去了所有的异常信息(更确切地说,你从来没有这样做 – 当没有可用的处理程序并且在调用地点做出决定时,终止被调用)。 如果没有适用于此的处理程序,则甚至不会创建异常对象。
我熟悉的最干净的解决方案如下所示:
void standard_exception_handler(); try { whatever(); } catch (...) { standard_exception_handler(); } void standard_exception_handler() { try { throw; // a bare throw preserves the original exception information } catch (const std::exception& ex) { ... } catch (const other_exception& ex) { ... } }
为了在公共处理程序之外拥有处理程序,您需要让公共处理程序在已知类型上运行(例如,更改catch (...)
以catch (const my_exception& ex)
,并在通用处理程序中进行必要的更改),或者使用嵌套的try
块:
try { try { whatever(); } catch (...) { standard_exception_handler(); } } catch (const who_knows& ex) { // log and exit }
我可以改进它,但是我想我可以
std::terminate
是用来打印std::exception
的what():
行 ) main
根本不知道它 有了这个,我的main
不必“知道”这个异常到出口代码的翻译,这是我的目标:
#include <stdexcept> #include <cstdlib> struct Someclass1 {}; struct Someclass2 {}; bool hasDefaultExceptionHandler = (std::set_terminate([](){ try { throw; } catch(const Someclass1& e){ exit(2); } catch(const Someclass2& e){ exit(3); } catch(...){ exit(1); } }), true); // Main has no idea int main(){ throw Someclass2{}; } //will exit with 3
感谢大家的好主意。