在我的每个主要功能中,我想捕获某些类别的异常并将它们转换为退出代码。
是否有更优雅的解决方案,比使用宏来开始和结束每个主要功能,将粘贴我想要的隐式try {} catch
?
我可以通过std::set_terminate
功能以某种方式实现这一目标吗?
示例:
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; }
}
答案 0 :(得分:6)
A clean way涉及使用翻译函数和所有异常样板,它返回相应异常的退出值。
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
});
}
答案 1 :(得分:1)
如果你愿意,我猜你可以用宏做某事。以下是:
#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
这个想法是让宏写一个尝试捕捉&#34;围绕&#34;主要功能体,这都是合法的。
int main() try { throw 1; } catch (int i) { return 0; }
答案 2 :(得分:1)
我通常这样做:
int main2();
int main() try {
return main2();
} catch(std::exception &e)
{
// some display...
}
当然,您可以拥有更多捕获处理程序。
如果您需要在多个入口点放置相同的捕获处理程序列表,那将是一个不同的问题。解决方案是catch(...) { foo(); }
,其中foo()
函数try { throw; }
后跟所有捕获处理程序。
答案 3 :(得分:0)
我对此表示怀疑。在调用终止时,您已经丢失了所有异常信息(更准确地说,您从未使用过它 - 当没有可用的处理程序且在呼叫站点进行确定时调用终止)。当没有适用于此的处理程序时,甚至不会创建异常对象。
答案 4 :(得分:0)
我熟悉的cleanest solution看起来像:
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
}
答案 5 :(得分:0)
我可能会改进它,但我发现我可以
std::terminate
does to print the
what():
line for std::exception
s)main
完全不了解它有了这个,我的main
s不必“知道”这个异常到exitcode的翻译,这是我的目标:
#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
感谢大家的好主意。