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

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

本文关键字:ptr operator 抛出 unique 情况下 std 在什么      更新时间:2023-10-16

我的类有一个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函数调用它是否安全?

长话短说,unique_ptr::operator[]是否有可能抛出

是的。它将简单地在它所具有的指针类型上使用[]。这可能会让人失望。回想一下,多亏了deleter体操,指针类型不需要是实际的指针。它可以是一个用户定义的对象类型,具有自己的operator[]重载,可以引发越界使用。

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

我浏览了noexcept引用,我的理解是noexcept只是指示函数不应该抛出异常,这样编译器就可以进行更具攻击性的优化。至于为什么unique_ptr::operator[]不是noexcept,我猜标准化者认为一些实现者可能会抛出,而另一些实现者则可能不会。我的观点是,unique_ptr::operator[]可能会抛出,这取决于unique_ptr的实现(通常是在索引越界时)。但是,根据代码的上下文,您可以确保不会发生这种情况,并决定为运算符[]指定noexcept