unique_ptr::deleter_type::pointer 是干啥用的?

Posted

技术标签:

【中文标题】unique_ptr::deleter_type::pointer 是干啥用的?【英文标题】: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] 容器和智能指针”,但这并不能完全说明问题。

【问题讨论】:

【参考方案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 中也很有用。

【讨论】:

以上是关于unique_ptr::deleter_type::pointer 是干啥用的?的主要内容,如果未能解决你的问题,请参考以下文章