是否可以安全地使用catch语句外部的异常(如果它保存在std :: exception_ptr中)? [英] Is it safe to use an exception outside the catch statement if it is held in a std::exception_ptr?

查看:559
本文介绍了是否可以安全地使用catch语句外部的异常(如果它保存在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆