C ++ 17引入了一个新函数std::uncaught_exceptions
:
检测已抛出或重新抛出的异常数,但尚未输入匹配的catch子句。
以下代码:
#include <iostream>
using namespace std;
struct A
{
~A()
{
cout << std::uncaught_exceptions() << endl;
}
};
int main()
{
try
{
try
{
A a1;
throw 1;
}
catch (...)
{
A a2;
throw;
}
}
catch (...)
{
A a3;
}
}
输出:
1
1
0
是否可以同时拥有两个或更多活动异常?
有什么例子吗?
是。从因处理另一个异常的堆栈展开而被调用的析构函数中抛出异常:
struct D
{
~D()
{
std::cout << std::uncaught_exceptions() << std::endl;
}
};
struct E
{
~E()
{
try
{
D d_;
throw 2;
}
catch(...)
{
std::cout << std::uncaught_exceptions() << std::endl;
}
}
};
int main()
{
try
{
D d;
E e;
throw 1;
}
catch(...)
{
}
}
d
的析构函数将被调用,而1
仍然是一个活跃的例外。所以std::uncaught_exceptions()
里面的~d
将是1。
对于e
,它的析构函数将被调用,而1
是一个活跃的例外。它的析构函数将被调用。它将构建一个D
,然后再投掷。但由于1
和2
都没有被抓住,std::uncaught_exceptions()
内的~d_
将是2。
std::uncaught_exceptions
的整个目的是检测这种情况。它允许您知道对象是否因堆栈展开或正常执行而被销毁。这可以让您知道是否应该进行不同类型的清理。考虑一个RAII对象,如果它由于堆栈展开而被销毁,它将回滚一个事务。