2013-08-07 15 views
7

naprawdę jak std :: throw_with_nested w C++ 11 ponieważ emuluje Java printStackTrace(), ale teraz jestem po prostu ciekawy, jak złapać zagnieżdżony wyjątek, na przykład:Zastosowanie throw_with_nested i złapać wyjątek zagnieżdżonych

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

Wcześniej myślałem, że std :: throw_with_nested generuje nowy wyjątek, który jest wielokrotnie uzyskiwany z dwóch wyjątków (std :: runtime_error i SomeException), ale po przeczytaniu jakiegoś tutorialu online, zawiera on wyjątek SomeStreception w std :: exception_ptr i jest prawdopodobne, dlaczego mogę to zrobić Złap to.

Potem zdałem sobie sprawę, że mogę to naprawić, używając std :: rethrow_if_nested (e), ale powyższy przypadek to tylko dwa poziomy, które są łatwe w obsłudze, ale myślę o bardziej ogólnej sytuacji, takiej jak 10 poziom złożony i po prostu nie chcę napisać std :: rethrow_if_nested 10 razy, aby sobie z tym poradzić.

Wszelkie sugestie będą naprawdę mile widziane.

+0

Zamiast powtarzać coś 10 razy, napisz pętlę lub funkcję rekursywną. –

+1

Wyjątek jest wielokrotnie uzyskiwany z 'std :: runtime_error' i' std :: nested_exception', ale NIE 'SomeException'. –

Odpowiedz

5

rozpakowania std::nested_exception jest łatwo osiągnąć poprzez rekurencję:

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

przypadku użycia może wyglądać następująco:

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

Demo to w akcji można znaleźć here.

+0

Czy twoje "e" jest w pierwszej funkcji cieniowane/cieniowanie? – NicholasM

+0

Tak, w zagnieżdżonym bloku catch, 'e' jest zacieniony. – tclamb

Powiązane problemy