2013-08-07 3 views
7

私は本当にSTDなどをキャッチ::それはJavaののprintStackTraceを(エミュレートするため、C++ 11にthrow_with_nested)が、今、私は、たとえば、ネストされた例外をキャッチするかどうかは、単に好奇心:使用しthrow_with_nestedとネストされた例外

void f() { 
    try { 
     throw SomeException(); 
    } catch(...) { 
     std::throw_with_nested(std::runtime_error("Inside f()")); 
    } 
} 
void g() { 
    try { 
     f(); 
    } catch(SomeException & e) { // I want to catch SomeException here, not std::runtime_error, :(
     // do something 
    } 
} 

以前は、私はstd :: throw_with_nestedが2つの例外(std :: runtime_errorとSomeException)から派生した新しい例外を生成すると思っていましたが、オンラインチュートリアルを読んだ後にはSomeExceptionがstd :: exception_ptrにカプセル化され、それを捕まえて。

私はstd :: rethrow_if_nested(e)を使ってこれを修正できることを認識しましたが、上記のケースは扱いが簡単な2つのレベルですが、10レベルの折り畳みのようなより一般的な状況を考えると、それを処理するためにstd :: rethrow_if_nestedを10回書く。

本当にありがとうございます。

try { 
    throws(); 
} catch(const std::exception& e) { 
    try { 
     rethrow_unwrapped(e); 
    } catch (const SomeException& e) { 
     // do something 
    } 
} 

アクションで、このデモがhereを見つけることができます。使い方は次のようになります

template<typename E> 
void rethrow_unwrapped(const E& e) 
{ 
    try { 
     std::rethrow_if_nested(e); 
    } catch(const std::nested_exception& e) { 
     rethrow_unwrapped(e); 
    } catch(...) { 
     throw; 
    } 
} 

std::nested_exceptionをアンラップ

+0

何かを何回か繰り返す代わりに、ループまたは再帰関数を記述します。 –

+1

例外は 'std :: runtime_error'と' std :: nested_exception'から派生しますが、 'SomeException'ではありません。 –

答えて

5

は容易に再帰を介して達成されます。

+0

あなたの 'e'は最初の関数でシャドーイングですか? – NicholasM

+0

はい、ネストされたキャッチブロック内では、 'e'がシャドウされます。 – tclamb

関連する問題