【问题标题】:What is unique_ptr::deleter_type::pointer for?unique_ptr::deleter_type::pointer 是干什么用的?
【发布时间】:2014-02-08 00:20:12
【问题描述】:

std::unique_ptr<T,D> 指定存储的不是您可能期望的T*,而是std::unique_ptr<T,D>::pointer 类型的对象。如果存在这种类型,则基本定义为D::pointer,否则定义为T*。因此,您可以通过适当地自定义删除器来自定义底层原始指针类型。

什么时候做这个是个好主意?这有什么用途?我能找到的唯一讨论是 this note,它暗示“在共享内存上下文中更好地支持 [ing] 容器和智能指针”,但这并不能完全说明问题。

【问题讨论】:

    标签: c++ c++11 unique-ptr


    【解决方案1】:

    很明显,当deleter 不对T* 值进行操作时使用它。这就是deleter 可以指定与T* 不同的数据类型的原因。一个常见的用例是 Win32 句柄:

    Using std::unique_ptr for Windows HANDLEs

    【讨论】:

    • 不错。我认为结果是:unique_ptr<T, D> 的行为类似于T,但其内部状态是pointer。在大多数情况下,指针是T *,但它可以是任何你想要的,只要它可以取消引用以产生T 并且可以为空。
    • 也就是说,如果您愿意相信HANDLE = void *,您可以使用std::unique_ptr<void, BOOL WINAPI(*)(void *)> p(..., FindVolumeClose)。那需要的写作要少得多。
    • @KerrekSB:您应该使用decltype(),正如其他讨论中的示例所示:std::unique_ptr<void, decltype(&FindVolumeClose)> p(..., FindVolumeClose)
    • 出于某种原因,在这种情况下,我不是decltype 的忠实粉丝。我宁愿将整个东西包装成一个制造商函数:std::unique_ptr<void, BOOL WINAPI(*)(void*)> make_unique_volume(...)。使用类型别名unique_volume_handle 将非常易读,并且用户永远不需要知道删除功能。只是我个人的看法。 (好吧,这实际上再次与自定义删除器非常相似,但出于异常安全原因,函数调用是好的。)
    • @KerrekSB:为什么要明确说明函数签名?让编译器自己计算签名,从而避免用户在键入签名时出错的任何可能性,尤其是在签名错误发生变化时。
    【解决方案2】:

    最初的动机是启用boost::offset_ptr 作为unique_ptr 下的表示,这将启用unique_ptr 在进程共享内存中的使用。进程共享内存中的结构不应包含指针或引用,只能包含偏移量。

    我很高兴得知同样的功能在 Windows API 中也很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-05
      • 2021-06-10
      • 1970-01-01
      • 2016-10-30
      • 2017-11-03
      • 2014-12-20
      • 2021-07-20
      • 1970-01-01
      相关资源
      最近更新 更多