2015-12-08 53 views
8

在我的每个主要函数中,我想捕获某些类的异常并将它们转换为退出代码。一个隐含的try {}抓住主

有没有比这个更优雅的解决方案比起始和结束每个主要功能的宏都会粘贴隐含的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; } 
} 
+3

是否所有你的例外与继承有关(或者他们可以?) – quamrana

+0

@quamrana是的。它实际上可能只是关于一个虚拟基类。 – PSkocik

+2

然后,您可以让每个异常类嵌入返回码,并且'main()'中的一个try/catch可以提取并返回它。 – quamrana

回答

6

A clean way涉及使用翻译功能与您的所有异常boilerplate,返回相应异常的退出值。

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 
    }); 
} 
0

我怀疑如此。在终止被调用的时候,你已经失去了所有的异常信息(更确切地说,你从来没有这样做 - 当没有可用的处理程序并且在呼叫站点做出决定时调用终止)。当没有适用于此的处理程序时,甚至不会创建异常对象。

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 

这个想法是让宏写一个try catch在主要函数体的“周围”,这都是合法的。

int main() try { throw 1; } catch (int i) { return 0; } 

little example live

1

我通常这样做:

int main2(); 

int main() try { 
    return main2(); 
} catch(std::exception &e) 
{ 
    // some display... 
} 

你可以有,当然更多的catch处理。


如果您需要在多个入口点放置相同的捕获处理程序列表,那将是一个不同的问题。解决方案有catch(...) { foo(); },其中foo()功能try { throw; }后跟所有捕获处理程序。

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 
} 
0

我仍然可以完善它,但我想通了,我可以

有了这个,我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 

感谢大家的好主意。