我有一个std::exception_ptr
,其中有一个例外。我将调用std::rethrow_exception
来获取实际异常,异常在catch语句之后是否有效?我的猜测是,因为我仍然持有std::exception_ptr
,它仍然有效。
参见示例:
std::exception_ptr ePtr = initialize_somewhere_else();
std::runtime_error* a=NULL;
try {
std::rethrow_exception(ePtr);
} catch(std::runtime_error& e) {
a = &e;
}
std::cout << a << ", " << a->what() << std::endl;
注意:在我使用Clang的测试中,这确实有效。
答案 0 :(得分:3)
如果它在std :: exception_ptr中保存,那么在catch语句之外使用异常是否安全?
<德尔>是。您可以将exception_ptr
视为指向异常的引用计数指针。只要exception_ptr
引用它,该例外就会存在,而不再存在。
此外, rethrow_exception
不会复制。
抱歉,我认为我的答案不正确。
这是检测测试:
#include <iostream>
#include <exception>
#include <stdexcept>
int
main()
{
auto ePtr = std::make_exception_ptr(std::runtime_error("some text"));
std::runtime_error* a = nullptr;
try
{
std::rethrow_exception(ePtr);
}
catch(std::runtime_error& e)
{
a = &e;
}
*a = std::runtime_error("other text");
try
{
std::rethrow_exception(ePtr);
}
catch(const std::runtime_error& e)
{
std::cout << e.what() << '\n';
}
}
在gcc和clang上输出:
other text
这表示a
和ePtr
指的是完全相同的对象。
然而VS,根据http://webcompiler.cloudapp.net输出的当前版本:
some text
这表示a
和ePtr
引用了不同的对象。
现在的问题是VS是否符合这方面的要求。我的观点是,它并不重要。这是标准的一个有争议的领域,如果有争议,标准将被改变以符合现有的做法。
在我看来rethrow_exception
在VS上制作副本,这意味着原始问题中e
的生命周期不能保证与ePtr
相关联。