为什么 unique_ptr 的 operator* 不是 noexcept ?

9
在我为我的兴趣OS实现基本的std库时,我遇到了这个问题,并想知道为什么:
operator->()和T* get()都被标记为noexcept,但是operator*()却没有。根据参考文献,它应该等同于*get(),这将使它能够成为noexcept,并且在查看一些实现时,我看不出它为什么不是。
为什么unique_ptr的解引用运算符没有标记为noexcept?

我投票关闭此问题,因为它仅仅基于对cplusplus的信任而产生的错误,并且在其他来源上无法再现。 - Yakk - Adam Nevraumont
2个回答

8
因为std::unique_ptrpointer类型的operator*可能会抛出异常。pointer类型别名被定义为std::remove_reference::type::pointer,如果该类型存在,则必须满足NullablePointer,否则为T*。它可能是一个重载了operator*的类类型,而不是T*

我只是想知道在这种情况下标记 -> noexcept 是否是一个好的实践。从技术上讲,确实是 noexcept 的,但实际上抛出异常被延迟到返回对象的解引用时。一个简单的表达式 a->b 可能 会抛出异常。这会导致一些混淆。 - llllllllll
@liliscent - 是的,表达式可能会抛出异常,但它不是unique_ptr重载函数中异常逃逸的地方。这个说明符是合适的,因为该函数是非抛出的,即使表达式可能会抛出异常。 - StoryTeller - Unslander Monica

6

来自cppreference

  • typename std::add_lvalue_reference<T>::type operator*() const; (1) (自 C++11 起)
  • pointer operator->() const noexcept; (2) (自 C++11 起)

然后:

异常情况:
1) 可能会抛出异常,例如如果 pointer 定义了一个抛出的 operator*


谢谢,我之前使用的是cplusplus.com,但它没有关于throwing的信息。 - Thalhammer
1
但为什么它不是有条件的noexcept呢?几乎所有的时间,都会使用普通指针,在这种情况下,*foo.get()noexcept的,但*foo却不是。我知道在实践中这并不重要,因为所有这些都将被inline - Arne Vogel
这种精度实际上不在标准中,但我认为这就是预期的结果。 - Quentin
2
@ArneVogel - 请查看LWG问题2762 - StoryTeller - Unslander Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接