c++ - 检测是否正在执行 catch block

标签 c++ exception try-catch

我有一个通过现有代码使用的错误记录功能。如果可能的话,我想通过检测何时从 catch block 调用它来改进它,以便在异常可用时从异常中提取附加信息。在 catch block 期间,您可以重新抛出异常并在本地捕获它。

void log_error()
{
    try {
        throw;  // Will rethrow the exception currently being caught
    }
    catch (const std::exception & err) {
        // The exception's message can be obtained
        err.what();
    }
}

如果您不在 catch block 的上下文中,此函数将调用 std::terminate。我正在寻找一种方法来检测是否存在要重新抛出的异常,调用 throw; 是否安全?我找到了 std::uncaught_exception但它似乎只适用于作为抛出异常的一部分执行的函数,在 catch block 中是无用的。我已经通读了 http://en.cppreference.com/w/cpp/error但我似乎找不到任何适用的机制。

#include <stdexcept>
#include <iostream>

struct foo {
    // prints "dtor : 1"
    ~foo() { std::cout << "dtor : " << std::uncaught_exception() << std::endl;  }
};

int main()
{
    try
    {
        foo bar;
        throw std::runtime_error("error");
    }
    catch (const std::runtime_error&)
    {
        // prints "catch : 0", I need a mechanism that would print 1
        std::cout << "catch : " << std::uncaught_exception() << std::endl;
    }
    return 0;
}

我发现的解决方法包括简单地实现一个从 catch block 中调用的不同函数,但此解决方案不具有追溯力。另一种方法是使用带有自定义异常类的 thread_local 标志来了解当前线程何时构造异常但未销毁它,但这似乎容易出错并且与标准和现有异常类不兼容。此弱解决方法的示例:

#include <exception>

struct my_base_except : public std::exception
{
    my_base_except() { ++error_count; }
    virtual ~my_base_except() { --error_count; }
    my_base_except(const my_base_except &) { ++error_count; }
    my_base_except(my_base_except&&) { ++error_count; }

    static bool is_in_catch() {
        return error_count > 0;
    }

private:
    static thread_local int error_count;
};

thread_local int my_base_except::error_count = 0;

void log_error()
{
    if (my_base_except::is_in_catch())
    {
        // Proceed to rethrow and use the additional information
    }
    else
    {
        // Proceed with the existing implementation
    }
}

是否存在解决此问题的标准功能?如果没有,是否有比我在此处确定的解决方法更强大的解决方法?

最佳答案

std::current_exception可能正是您正在寻找的。

std::current_exception返回 std::exception_ptr ,这是指向当前处理的异常的指针类型,或 nullptr如果没有处理异常。可以使用 std::rethrow_exception 重新抛出异常.

关于c++ - 检测是否正在执行 catch block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43666935/

相关文章:

scala - 了解 play/scala 错误处理

c++ - std::vector new 内存不足

c++ - 将 itoa 与 TCHAR 一起使用

C# – try{}catch(Exception ex){} – 不捕获任何异常

Java 无法序列化包含带有比较器的 TreeMap 的对象

Python:捕获两个异常之一

c++ - c++测试程序中的非法系统调用(对角矩阵元素求和程序)

c++ - 在 BOOST 图中找到给定 2 个顶点的多条边

java - 尝试在 Android 中使用 AESCounterRNG

R 函数返回值以及警告消息