我有一个 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 的测试中,这确实有效。
最佳答案
Is it safe to use an exception outside the catch statement if it is held in a std::exception_ptr?
是的。您可以将 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
.
关于c++ - 如果异常保存在 std::exception_ptr 中,那么在 catch 语句之外使用异常是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30462906/