我非常喜欢c 11中的std :: throw_with_nested,因为它模拟了
java的printStackTrace()但是现在我只是好奇如何捕获嵌套异常,例如:
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会生成一个新的异常,它是从两个异常(std :: runtime_error和SomeException)中派生而来的,但在阅读了一些在线教程之后,它将someException封装在std :: exception_ptr中,并且它可能是为什么我可以抓住它.
然后我意识到我可以通过使用std :: rethrow_if_nested(e)解决这个问题,但上面的情况只有两个级别,很容易处理,但考虑更一般的情况,如10级折叠,我只是不想写std: :rethrow_if_nested 10次来处理它.
任何建议都会非常感激.
解决方法
通过递归很容易地解开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 } }
可以在here找到这个实际的演示.