【问题标题】:C++ catch exception in a loop and rethrow _after_ the loop finishes?C++ 在循环中捕获异常并在循环结束后重新抛出?
【发布时间】:2019-05-10 12:59:39
【问题描述】:

目标是完全处理一个循环并抛出之后可能发生的任何异常:

for (...) {
   try {
      // code that could throw
   } catch (const ExceptionObj &ex) {
      // save ex and rethrow after the loop
   }
}

这样做的最佳做法是什么?在我的特殊情况下,保存 任何 异常是可以的。

我有几个想法:

  1. ex 复制到ExceptionObj 值。问题:当 ex 有子类或需要处理更多异常时,根本无法很好地扩展。

  2. ExceptionObj 中有一个clone 方法,它返回堆上的副本。问题:不适用于第三方异常。

【问题讨论】:

    标签: c++ c++11 exception-handling


    【解决方案1】:

    以这种类型擦除的方式处理抛出的异常对象是 std::exception_ptr 存在的目的:

    std::exception_ptr ex;
    for (...) {
       try {
          // code that could throw
       } catch (...) {
          ex = std::current_exception();
       }
    }
    if(ex) // Only evaluates to true if a thrown exception was assigned to it.
        std::rethrow_exception(ex);
    

    所有与异常对象的动态类型相关的生命周期问题都由标准库处理。您可以将 ex 视为异常对象的引用计数句柄,允许您将其提升到 try-catch 块之外。

    这遵循您在帖子中列出的方法,然后在评论中确认,最后抛出的异常是被重新抛出的异常。

    【讨论】:

    • 一些吹毛求疵:根据实现(和条件),您最终可能会: 1. 重新抛出 std::bad_alloc(或 std::bad_exception)而不是用户异常; 2. 未指定的行为,如果没有内存可以在可以抛出它(另一个对象)的各个点分配另一个异常对象。诚然,所有这些只有在堆(几乎)耗尽时才会发生。另外,您最终可能会得到保证调用异常 cctor...如果它总是抛出 smth else - 您将永远无法重新抛出原始异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 2017-04-10
    相关资源
    最近更新 更多