为什么C ++不使用std :: nested_exception允许从析构函数中抛出? [英] Why doesn't C++ use std::nested_exception to allow throwing from destructor?

查看:85
本文介绍了为什么C ++不使用std :: nested_exception允许从析构函数中抛出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从析构函数中抛出异常的主要问题是,在调用析构函数时,另一个异常可能是在飞行中( std :: uncaught_exception()== true ),因此在这种情况下该怎么办并不明显。用新异常覆盖旧异常将是处理这种情况的一种可能方法。但已决定在这种情况下必须调用 std :: terminate (或另一个 std :: terminate_handler )。

The main problem with throwing exceptions from destructor is that in the moment when destructor is called another exception may be "in flight" (std::uncaught_exception() == true) and so it is not obvious what to do in that case. "Overwriting" the old exception with the new one would be the one of the possible ways to handle this situation. But it was decided that std::terminate (or another std::terminate_handler) must be called in such cases.

C ++ 11通过 std :: nested_exception 类引入了嵌套异常功能。此功能可用于解决上述问题。可以将旧的(未捕获的)异常嵌套到新的异常中(反之亦然?),然后可以抛出该嵌套的异常。但是这个想法没有被使用。在这种情况下,在C ++ 11和C ++ 14中仍会调用 std :: terminate

C++11 introduced nested exceptions feature via std::nested_exception class. This feature could be used to solve the problem described above. The old (uncaught) exception could be just nested into the new exception (or vice versa?) and then that nested exception could be thrown. But this idea was not used. std::terminate is still called in such situation in C++11 and C++14.

因此问题。是否考虑过嵌套异常的想法?有什么问题吗?

So the questions. Was the idea with nested exceptions considered? Are there any problems with it? Isn't the situation going to be changed in the C++17?

推荐答案

在C ++ 17中不会改变这种情况吗?在堆栈展开过程中被执行(当您的对象不是在堆栈展开过程中创建时) 1 ,并且析构函数需要发出异常。

The problem you cite happens when your destructor is being executed as part of the stack unwinding process (when your object was not created as part of stack unwinding)1, and your destructor needs to emit an exception.

那如何工作?您有两个例外。 X 是导致堆栈退出的异常。异常 Y 是析构函数要抛出的异常。 nested_exception 只能容纳其中的

So how does that work? You have two exceptions in play. Exception X is the one that's causing the stack to unwind. Exception Y is the one that the destructor wants to throw. nested_exception can only hold one of them.

所以也许您有例外情况 Y 包含一个 nested_exception (或者可能只是一个 exception_ptr )。那么...您如何在 catch 网站上处理该问题?

So maybe you have exception Y contain a nested_exception (or maybe just an exception_ptr). So... how do you deal with that at the catch site?

如果您捕获了 Y ,并且恰好有一些嵌入式 X ,您如何获得它?请记住: exception_ptr 已被类型擦除;除了传递它之外,您唯一可以做的就是将它扔掉。人们应该这样做吗?

If you catch Y, and it happens to have some embedded X, how do you get it? Remember: exception_ptr is type-erased; aside from passing it around, the only thing you can do with it is rethrow it. So should people be doing this:

catch(Y &e)
{
  if(e.has_nested())
  {
    try
    {
      e.rethrow_nested();
    }
    catch(X &e2)
    {
    }
  }
}

我看不到很多人这样做。尤其是因为存在大量 X -es。

I don't see a lot of people doing that. Especially since there would be an exceedingly large number of possible X-es.

1 :请不要使用 std :: uncaught_exception()== true 来检测这种情况。这是非常有缺陷的。

1: Please do not use std::uncaught_exception() == true to detect this case. It is extremely flawed.

这篇关于为什么C ++不使用std :: nested_exception允许从析构函数中抛出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆