C++推断嵌套异常的类型

标签 c++ c++11 exception c++14 c++17

简介:

给出:

struct X : std::runtime_error {
  using std::runtime_error::runtime_error;
};

当我们调用 std::throw_with_nested(X("foo")) 时,实际抛出的不是 X。它是从 Xstd::nested_exception 派生的某种类型。

因此,下面的断言将失败:

const std::type_info *a = nullptr, *b = nullptr;
try
{
  throw X("1");
}
catch(X& x) {
  a = std::addressof(typeid(x));
  try {
    std::throw_with_nested(X("2"));
  }
  catch(X& x) {
    b = std::addressof(typeid(x));
  }
}
assert(std::string(a->name()) == std::string(b->name()));

我想做的是推断这两个异常是相关的。

第一次尝试:

        std::type_index
        deduce_exception_type(const std::exception* pe)
        {
            if (auto pnested = dynamic_cast<const std::nested_exception*>(pe))
            {
                try {
                    std::rethrow_exception(pnested->nested_ptr());
                }
                catch(const std::exception& e)
                {
                    return deduce_exception_type(std::addressof(e));
                }
            }
            else {
                return typeid(*pe);
            }
        }

这会失败,因为 std::nested_exception::nested_ptr() 返回指向下一个异常的指针,而不是当前异常的 X 接口(interface)。

我正在寻找(可移植的)想法和解决方案,使我能够从标准库在 std::rethrow_exception 期间抛出的“名称未知的异常”中恢复 typeid(X)。

c++14 和 c++1z 都可以。

为什么?

因为我希望能够解开一个完整的异常层次结构并通过 rpc session 传输它,完成异常类型名称。

理想情况下,我不想编写一个包含系统中所有异常类型的 catch block ,这必须按派生深度进行弱排序。

预期功能的进一步示例(以及为什么我的方法不起作用的说明):

const std::type_info *b = nullptr;
try
{
  throw std::runtime_error("1");
}
catch(std::exception&) {
  try {
    std::throw_with_nested(X("2"));
  }
  catch(X& x) {
    // PROBLEM HERE <<== X& catches a std::_1::__nested<X>, which 
    //                is derived from X and std::nested_exception
    b = std::addressof(typeid(x));
  }
}
assert(std::string(typeid(X).name()) == std::string(b->name()));

最佳答案

改编自 http://en.cppreference.com/w/cpp/error/nested_exceptionprint_exception :

const std::type_info&
deduce_exception_type(const std::exception& e)
{
    try {
        std::rethrow_if_nested(e);
    } catch(const std::exception& inner_e) {
        return deduce_exception_type(inner_e);
    } catch(...) {
    }
    return typeid(e);
}

Demo

关于C++推断嵌套异常的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37256377/

相关文章:

java - 处理一个不存在的 servlet 异常

java - 相应 try 语句的主体中永远不会抛出异常

c++ - pthreads 和 C++

C++:带有 packaged_task 的核心转储

C++ 标记强制保留参数为 nullptr

c# - 嵌套 LINQ 方法抛出 `Not Supported...` 异常

c++ - 将 std::lower_bound 与 std::vector::const_iterator 一起使用

c++ - TDD、单元测试和架构变更

C++可变参数模板构造函数和通用构造函数

C++ operator<< gtest AssertionFailure 编译错误