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 是干啥用的?的主要内容,如果未能解决你的问题,请参考以下文章