2015-12-08 54 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 

感謝大家的好主意。