>C++17引入了一个新函数std::uncaught_exceptions
:
检测已引发或重新引发但尚未引发的异常数 输入其匹配的捕获子句。
以下代码:
#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
仍然是一个活动的异常时被调用。所以~d
里面std::uncaught_exceptions()
将是 1。
对于e
,它的析构函数将被调用,而1
是一个活动的异常。将调用其析构函数。它将构造一个D
,然后再次抛出。但由于此时1
和2
都没有被抓住,~d_
内部的std::uncaught_exceptions()
将是2。
std::uncaught_exceptions
的全部目的是检测这种情况。它允许您知道对象是由于堆栈展开还是正常执行而被销毁。这让您知道是否应该执行不同类型的清理。考虑一个 RAII 对象,如果事务由于堆栈展开而被销毁,它将回滚事务。