是否可以安全地使用catch语句外部的异常(如果它保存在std :: exception_ptr中)? [英] Is it safe to use an exception outside the catch statement if it is held in a std::exception_ptr?
问题描述
我有一个 std :: exception_ptr
里面有一个异常。我将调用 std :: rethrow_exception
获取实际的异常,该异常在catch语句后是否有效?我猜这里是因为我仍然持有 std :: exception_ptr
它仍然是有效的。
I have a std::exception_ptr
with an exception inside it. I am going to invoke std::rethrow_exception
to get the actual exception, will the exception be valid after the catch statement? My guess here is that since I still hold the std::exception_ptr
it will still be valid.
示例:
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的测试中,这是行之有效的。
Note: In my tests using Clang this does work.
推荐答案
在catch语句之外使用异常是安全的:: exception_ptr?
Is it safe to use an exception outside the catch statement if it is held in a std::exception_ptr?
是的。您可以将 exception_ptr
视为异常的引用计数指针。只要 exception_ptr
指向它,而且不再指向它,该异常就会存在。
Yes. You can think of exception_ptr
as a reference-counted pointer to the exception. The exception will live for as long as an exception_ptr
refers to it, and no longer.
此外, rethrow_exception
不会复制。
Additionally, rethrow_exception
does not make a copy.
这是一个检测测试:
#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上输出:
On gcc and clang this outputs:
other text
这表明 a
和 ePtr
是指完全相同的对象。
This indicates that a
and ePtr
refer to the exact same object.
但是,VS,根据 http://webcompiler.cloudapp.net 输出的当前版本:
However VS, current version according to http://webcompiler.cloudapp.net outputs:
some text
这表示 a
和 ePtr
指的是不同的物件。
This indicates that a
and ePtr
refer to different objects.
现在的问题是VS是否符合这方面。我的意见是,它并不重要。
The question now is whether VS is conforming in this regard. My opinion is that it doesn't really matter. This is a contentious area of the standard, and if contested, the standard will be changed to match existing practice.
在我看来, rethrow_exception是标准的一个有争议的领域,如果有争议,
在VS上创建副本,这意味着原始问题中的 e
的生命周期不能保证与 ePtr
。
It appears to me that rethrow_exception
makes a copy on VS, and that implies that the lifetime of e
in the original question is not guaranteed to be tied to ePtr
.
这篇关于是否可以安全地使用catch语句外部的异常(如果它保存在std :: exception_ptr中)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!