7

java の printStackTrace() をエミュレートするので、c++11 の std::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) から複数回派生した新しい例外を生成すると考えていましたが、いくつかのオンライン チュートリアルを読んだ後、std::exception_ptr 内に SomeException をカプセル化し、おそらくそれをキャッチできない理由です。 .

次に、 std::rethrow_if_nested( e ) を使用してこれを修正できることに気付きましたが、上記のケースは扱いやすい 2 レベルのみですが、10 レベルの折り畳みなどのより一般的な状況を考えているため、std を書きたくないだけです。 :rethrow_if_nested を 10 回実行して処理します。

任意の提案をいただければ幸いです。

4

1 に答える 1

5

a のアンラップは、std::nested_exception再帰によって簡単に実現できます。

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

使用法は次のようになります。

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

この動作のデモは、ここにあります。

于 2014-02-27T06:09:58.807 に答える