下面的代码见unique_ptr.h
template <typename _Tp, typename _Dp>
class __uniq_ptr_impl
{
template <typename _Up, typename _Ep, typename = void>
struct _Ptr
{
using type = _Up*;
};
template <typename _Up, typename _Ep>
struct
_Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
{
using type = typename remove_reference<_Ep>::type::pointer;
};
public:
using _DeleterConstraint = enable_if<
__and_<__not_<is_pointer<_Dp>>,
is_default_constructible<_Dp>>::value>;
using pointer = typename _Ptr<_Tp, _Dp>::type;
//omit code below ...
}
我想知道哪个模板实际上适用于不同条件的
using pointer = typename _Ptr<_Tp, _Dp>::type;
(即不同类型的_Up
、_Ep
)。
标准库中的这段代码是 [unique.ptr.single.general] p3:
的实现如果 qualified-id
有效并表示类型 ([temp.deduct]),则remove_reference_t<D>::pointer
应为unique_ptr<T, D>::pointer
的同义词。 否则remove_reference_t<D>::pointer
应为unique_ptr<T, D>::pointer
的同义词。element_type*
在这段代码中,
_Ptr
的部分特化中的SFINAE用于判断typename remove_reference<_Ep>::type::pointer
是否是一个类型。标准措辞中的D
在此实现中是_Ep
。
如果是类型,则从删除器中取出pointer
;否则,主模板将 type
定义为 _Up*
,这使得 pointer
成为 element_type*
。
另请参阅我们如何将 void_t 用于 SFINAE? 以更深入地解释此技术。
另请参阅 有关 unique_ptr 内的原始指针类型,了解为什么自定义
pointer
而不是始终使用 element_type*
很有用。