C++ std::unique_ptr::重置检查托管指针空值?

C++ std::unique_ptr::重置检查托管指针空值?,c++,c++11,language-lawyer,unique-ptr,delete-operator,C++,C++11,Language Lawyer,Unique Ptr,Delete Operator,为了在我的源代码中使用C++11智能指针,我一直在阅读有关C++11智能指针的内容,我一直在阅读的文档是cppreference.com上的文档;在阅读有关std::unique_ptr的文章时,我发现有一个文档对我来说似乎不正确(我的重点是): 替换托管对象 给定当前\u ptr,由*this管理的指针按以下顺序执行以下操作: 保存当前指针的副本old\u ptr=current\u ptr 用参数current\u ptr=ptr覆盖当前指针 如果旧指针非空,则删除以前管理的对象If(ol

为了在我的源代码中使用C++11智能指针,我一直在阅读有关C++11智能指针的内容,我一直在阅读的文档是cppreference.com上的文档;在阅读有关std::unique_ptr的文章时,我发现有一个文档对我来说似乎不正确(我的重点是):

替换托管对象

  • 给定
    当前\u ptr
    ,由
    *this
    管理的指针按以下顺序执行以下操作:

  • 保存当前指针的副本
    old\u ptr=current\u ptr
  • 用参数
    current\u ptr=ptr
    覆盖当前指针
  • 如果旧指针非空,则删除以前管理的对象
    If(old\u ptr!=nullptr)get\u deleter()(old\u ptr)
<>在C++标准文档中,我们可以读取已知的删除空指针特征:

摘自
n3690
标准5.3.5删除(强调矿山):

如果删除表达式的操作数值不是空指针值,则:

-如果没有忽略要删除的对象的新表达式的分配调用,则删除表达式应调用解除分配函数。新表达式的分配调用返回的值应作为第一个参数传递给释放函数

-否则,删除表达式将不会调用解除分配函数

因此,我想知道为什么cppreference说
unique\u ptr::reset
函数在删除托管指针之前检查其空值,即使te standard说不会通过空指针调用释放函数(这就是为什么cppreference文档对我来说似乎不正确)

很明显,我一定是弄错了,这样做肯定是有原因的,但我无法想象这是什么原因。有什么提示吗


PS:标准中哪里定义了
std::unique\u ptr
必须如何实现或表现?在20.9.1类模板
unique\ptr
中,我找不到任何关于检查空值的内容。

是的,标准(C++11,
[unique.ptr.single.modifiers]§4
要求检查非空值:

4效果:将
p
分配给存储指针,然后如果存储指针的旧值
old\u p
不等于
nullptr
,则调用
get\u deleter()(old\u p)
。[注意:这些操作的顺序很重要,因为调用get_deleter()可能会破坏
*此
-结束注意]

(强调矿山)

讨论:将其标准化的另一种方法是将“负担”放在类的用户身上,即在对空指针调用时要求所有删除器(默认删除器和任何自定义删除器)正常工作


然而,我知道这个想法是为了让像
free()
这样的函数,甚至像一个假想的
unlock\u mutex(mutex*)
这样的东西,能够作为开箱即用的删除程序,而不管它们如何处理空指针。因此,将此检查放入
唯一\u ptr
本身可以扩大可直接使用的删除程序的选择范围。

如果您的删除程序不执行简单的删除操作,该怎么办?如果您的unique_ptr有一个执行其他操作的自定义删除器,您希望使用nullptr作为参数调用您的删除器吗D

delete
并不是摆脱指针式资源的唯一方法。你可以有一个自定义的删除器,它可以
释放
或者做其他不喜欢空指针的事情。如果删除空指针没有效果,那么这样做的原因是什么?@PaperBirdMaster如果删除器不是默认的删除器,并且不能使用空指针怎么办?我假设如果你创建一个自定义的删除器,该自定义删除程序必须符合某些条件,例如不要尝试在空指针上操作,但很明显,这是我的错误(我找不到有关自定义删除程序的任何条件/预编辑,因此这一定是原因:)@PaperBirdMaster是的,这将是标准的另一种选择。但是我知道这个想法是为了启用像
free()
这样的函数,甚至像一个假设的
unlock\u mutex(mutex*)
这样的东西都能像开箱即用的删除程序一样工作,所以他们决定把负担放在
unique\u ptr
上,而不是放在它的用户身上,你介意把这个解释写进未来读者的答案中吗?(即使在那之后,我已经接受了答案)如果我想允许使用空指针调用我的自定义deleter:我将检查deleter本身的空值;P但是现在我可以假设我的自定义删除程序不会被
nullptr
调用(即使我想,出于一些随机和奇怪的原因)@PaperBirdMaster实际上
delete
操作符检查空指针是一个奇怪的家伙,在这种语言中,你不应该为你不使用的东西付费(如果我从未删除过
nullptr
,为什么我还要支付额外的支票呢?),但我想是出于历史原因和模仿
free()的行为
之所以要检查
nullptr
,是因为似乎有足够多的编码器依赖于这种行为。您使用的同一个自定义删除程序也可以用于另一个上下文,在这种上下文中,检查
nullptr
没有多大意义,仅为空检查需要一个包装器将是令人难过的:)
void reset(pointer p = pointer()) noexcept;