std::unique_ptr try-catch 块中未捕获解引用异常

std::unique_ptr dereference exception not catch-ed in try-catch block

所以假设我有:

struct test {
    bool a;
    int b;
};

int main()
{
    std::unique_ptr<test> ptr;
    // don't init the ptr

    try
    {
        if (!ptr->a)
        {
            std::cout << "ok" << std::endl;
        }
    }
    catch (const std::exception &ex)
    {
        std::cout << "ex: " << ex.what() << std::endl;
    }

    return 1;
}

所以我在这里设置了一个唯一的指针,但我没有初始化它(在更大的代码库中模拟它)但我想捕获异常。

问题是我的异常没有被调用——我只是遇到了一个崩溃(内存访问错误)

我阅读了一些类似的问题(但不完全相同),建议我通过引用传递异常 - 但这没有用。

那么是否可以捕获 unique_ptr 取消引用异常?

编辑: 我应该补充一点,这是在 Windows 7 box 运行 MSVS2012 可执行文件上 - 以防它是相关的!

So is it possible to catch a unique_ptr de-reference exception?

没有要捕获的 unique_ptr 取消引用异常。

作为 documentation says,

The behavior is undefined if get() == nullptr

您可以使用这种类似于 Java 的行为轻松编写您自己的智能指针,但这确实意味着要为 每个 取消引用支付测试和分支费用,这通常看起来很愚蠢。

对于评论中描述的略有不同的问题:

I have a list of unique_ptr's - I was trying to avoid individually checking each one by putting a try block around it.

理智的解决方案可能是检查一次,而不是在随后的每次取消引用时都检查它:

if(any_of(begin(ptrs), end(ptrs), logical_not<unique_ptr<test>>{})
{
  throw MyNullPointerException();
}

根据后续评论,您可以在构造函数中添加一个检查并抛出包装器。

在 C++17 中,您几乎可以通过返回一个 optional<unique_ptr<test>> 来获得您想要的结果(即,它要么包含填充的 unique_ptr,要么什么都没有:在这种情况下,调用value 提取 unique_ptr 会抛出 std::bad_optional_access 如果那里真的没有)。

如果您可以导入 ot(或没有 C++17),GSL 可能会更好 gsl::not_null<T>。例如,您可以将这些东西存储在您的容器中

using unique_not_null = std::unique_ptr<gsl::not_null<test>>;