获取对 std::exception_ptr 持有的 std::exception 的引用

xyl*_*per 5 c++ error-handling

我正在尝试获取std::exceptionstd::exception_ptr.

这是我尝试过的:

#include <iostream>

using namespace std::literals;

auto unwrap(std::exception_ptr ptr) -> const std::exception &
{
    try {
        std::rethrow_exception(ptr);
    } catch (std::exception &e) {
        return e;
    }
}

int main()
{
    const auto ptr = std::make_exception_ptr(std::runtime_error{"test"});
    const auto &exp = unwrap(ptr);
    std::cout << exp.what() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用 GCC,标准输出显示“测试”,这正是我所期望的。但是,对于 MSVC 2019,标准输出显示“未知异常”。

我的源代码中是否有任何未定义、未指定或依赖于实现的行为?或者,它是编译器/标准库实现错误吗?

Tim*_*imo 1

由于某种原因,MSVC 会复制您的异常。不确定标准是否允许(请有人澄清)。下面的代码

#include <iostream>
#include <exception>
#include <stdexcept>

using namespace std::literals;

struct myerror : std::runtime_error
{
    using std::runtime_error::runtime_error;

    myerror(const myerror& o) : myerror(o.what())
    {
        std::cout << "exception is copied\n";
    }

    myerror(const myerror&& o) noexcept : myerror(o.what())
    {
        std::cout << "exception is moved\n";
    }
};

auto unwrap(std::exception_ptr ptr) -> const std::exception&
{
    try {
        std::rethrow_exception(ptr);
    }
    catch (std::exception const& e) {
        std::cout << e.what() << std::endl;
        return e;
    }
}

int main()
{
    std::exception_ptr ptr;
    try
    {
        throw myerror{ "test" };
    }
    catch (...)
    {
        ptr = std::current_exception();
    }
    const auto& exp = unwrap(ptr);
    std::cout << exp.what() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用 MSVC (16.9) 打印:

exception is copied
exception is copied
test
Unknown exception
Run Code Online (Sandbox Code Playgroud)

并伴随着叮当声:

test
test
Run Code Online (Sandbox Code Playgroud)

因此,您的异常引用在 MSVC 的情况下悬而未决。

神箭