在什么情况下 std::unique_ptr::operator[] 可能会抛出?

Under which circumstances might std::unique_ptr::operator[] throw?

我的 class 有一个 operator[],它所做的只是在 unique_ptr 成员上调用 std::unique_ptr::operator[]。相关部分就是这样:

template <typename T> struct Foo {
    T& operator [](const size_t pos) const noexcept
    {
        return data_[pos];
    }

    std::unique_ptr<T[]> data_;
};

我已将运算符标记为 noexcept。但是,unique_ptr::operator[] 而不是 noexcept。我无法找出原因,也不知道我是否可以假设它永远不会抛出。 unique_ptr::operator[] 本身没有在文档中列出任何异常(cppreference 和 MSDN 声称它没有定义它可能抛出的任何异常列表。)

所以我假设缺少的 noexcept 可能是:a) 一个错误,或者 b) 运算符访问的基础数据类型可能会抛出异常。选项 a 会很好,因为这意味着我可以标记我自己的运算符 noexcept。选项 b 会很难理解,因为所有的运算符都会得到一个引用并且它不会调用任何东西。

所以,长话短说,有没有可能 unique_ptr::operator[] 抛出,从 noexcept 函数调用它是否安全?

我想我试一试(我不确定答案)。

我查看了 noexcept reference,我的理解是 noexcept 只是表明函数 不应该 抛出异常,以便编译器 可以进行更积极的优化。 至于为什么 unique_ptr::operator[] 不是 noexcept 猜测 标准化的人认为一些实现者可能会抛出而另一些可能不会。 我的意见是 unique_ptr::operator[] 可能会抛出取决于 unique_ptr 的实现(通常是当索引超出范围时)。 但是,根据代码的上下文,您可以确保不会发生这种情况,并决定为您的 operator[].

指定 noexcept

So, long story short, is there any possibility of unique_ptr::operator[] ever throwing

是的。它只会在它拥有的指针类型上使用 [] 。那可能会抛出。回想一下,由于删除体操,指针类型不必是实际指针。它可以是一个用户定义的对象类型,具有自己的 operator[] 重载,可能会引发越界使用。