先看一个:
template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>constexpr unique_ptr() noexcept: _Mybase(pointer()){ // default construct}注意_Dx2是来自_Dx,这个_Dx是自定义删除器。
_Unique_ptr_enable_default_t<_Dx2> = 0用于对自定义删除器的sfine的验证
看看_Unique_ptr_enable_default_t是怎么个事。
省流:_Unique_ptr_enable_default_t<_Dx2>表示_Dx2需要满足:不能是指针+有默认的构造函数
struct Position
{Position(double x, double y) : x(x), y(y){std::cout << "Position(" << x << "," << y << ")" << std::endl;}Position(){std::cout << "Position()" << std::endl;}~Position(){std::cout << "~Position("<<x<<","<<y<<")" << std::endl;}double x = 0.0f;double y = 0.0f;
};void fun()
{std::unique_ptr<Position> pos = std::make_unique<Position>(1.0, 2.0);
}template<class _Dx2>
using _Unique_ptr_enable_default_t =
enable_if_t<conjunction_v<negation<is_pointer<_Dx2>>,is_default_constructible<_Dx2>>, int>;替换了类型之后:
template<class Position>
using _Unique_ptr_enable_default_t =
enable_if_t<conjunction_v<negation<is_pointer<std::default_delete<Position>>>,is_default_constructible<std::default_delete<Position>>>, int>;conjunction_v< negation<is_pointer<std::default_delete<Position>>>, is_default_constructible<std::default_delete<Position>> >std::condition 功能:
std::conjunction<Bs...>::value // is true if all Bs... are true, false otherwisenegation应该是对true和false进行反向std::is_default_constructible是一个C++标准库中的类型特性,用于在编译时检查一个类型是否具有默认构造函数。如果类型有一个不带参数的构造函数,则认为该类型具有默认构造函数,否则没有。所以:
is_pointer<std::default_delete<Position>> : false
negation<is_pointer<std::default_delete<Position>>> : true
is_default_constructible<std::default_delete<Position>> : true
conjunction_v< negation<is_pointer<std::default_delete<Position>>>, is_default_constructible<std::default_delete<Position>> >的结果
就是:
conjunction_v< true, true>::value : true那么:
enable_if_t<conjunction_v< true, true>::value, int> : int所以:
_Unique_ptr_enable_default_t<Position>的结果就是int
{int i = 123;std::unique_ptr<int> pos{ &i };std::ignore = pos;return 1;
}调用到:template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>explicit unique_ptr(pointer _Ptr) noexcept: _Mybase(_Ptr){ // construct with pointer}std::unique_ptr<int,std::default_delete<int> >::
unique_ptr<int,std::default_delete<int> ><std::default_delete<int>,0>
(int * _Ptr=0xcccccccccccccccc) 行 2212 C++
C++模板元一生之敌之:std::conjunction-CSDN博客
C++标准模板(STL)- 类型支持 (特性上的运算,变参的逻辑与元函数,std::conjunction)-CSDN博客
这下面几个,template里面,都是:
template<class _Dx2 = _Dx, _Unique_ptr_enable_default_t<_Dx2> = 0>
说明这几个构造函数是重载关系。template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>constexpr unique_ptr() noexcept: _Mybase(pointer()){ // default construct}template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>constexpr unique_ptr(nullptr_t) noexcept: _Mybase(pointer()){ // null pointer construct}unique_ptr& operator=(nullptr_t) noexcept{ // assign a null pointerreset();return (*this);}template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>explicit unique_ptr(pointer _Ptr) noexcept: _Mybase(_Ptr){ // construct with pointer}所以如果参数类型为指针的时候,这几个带_Unique_ptr_enable_default_t的就不会匹配成功
// CLASS TEMPLATE unique_ptr SCALAR
template<class _Ty,class _Dx> // = default_delete<_Ty>class unique_ptr: public _Unique_ptr_base<_Ty, _Dx>
{ // non-copyable pointer to an object
public:typedef _Unique_ptr_base<_Ty, _Dx> _Mybase;typedef typename _Mybase::pointer pointer;typedef _Ty element_type;typedef _Dx deleter_type;using _Mybase::get_deleter;template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>constexpr unique_ptr() noexcept: _Mybase(pointer()){ // default construct}template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>constexpr unique_ptr(nullptr_t) noexcept: _Mybase(pointer()){ // null pointer construct}unique_ptr& operator=(nullptr_t) noexcept{ // assign a null pointerreset();return (*this);}template<class _Dx2 = _Dx,_Unique_ptr_enable_default_t<_Dx2> = 0>explicit unique_ptr(pointer _Ptr) noexcept: _Mybase(_Ptr){ // construct with pointer}template<class _Dx2 = _Dx,enable_if_t<is_constructible_v<_Dx2, const _Dx2&>, int> = 0>unique_ptr(pointer _Ptr, const _Dx& _Dt) noexcept: _Mybase(_Ptr, _Dt){ // construct with pointer and (maybe const) deleter&}template<class _Dx2 = _Dx,enable_if_t<conjunction_v<negation<is_reference<_Dx2>>,is_constructible<_Dx2, _Dx2>>, int> = 0>unique_ptr(pointer _Ptr, _Dx&& _Dt) noexcept: _Mybase(_Ptr, _STD move(_Dt)){ // construct by moving deleter}template<class _Dx2 = _Dx,enable_if_t<conjunction_v<is_reference<_Dx2>,is_constructible<_Dx2, remove_reference_t<_Dx2>>>, int> = 0>unique_ptr(pointer, remove_reference_t<_Dx>&&) = delete;unique_ptr(unique_ptr&& _Right) noexcept: _Mybase(_Right.release(),_STD forward<_Dx>(_Right.get_deleter())){ // construct by moving _Right}template<class _Ty2,class _Dx2,enable_if_t<conjunction_v<negation<is_array<_Ty2>>,is_convertible<typename unique_ptr<_Ty2, _Dx2>::pointer, pointer>,conditional_t<is_reference_v<_Dx>, is_same<_Dx2, _Dx>, is_convertible<_Dx2, _Dx>>>, int> = 0>unique_ptr(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept: _Mybase(_Right.release(),_STD forward<_Dx2>(_Right.get_deleter())){ // construct by moving _Right}#if _HAS_AUTO_PTR_ETCtemplate<class _Ty2,enable_if_t<conjunction_v<is_convertible<_Ty2 *, _Ty *>,is_same<_Dx, default_delete<_Ty>>>, int> = 0>unique_ptr(auto_ptr<_Ty2>&& _Right) noexcept: _Mybase(_Right.release()){ // construct by moving _Right}#endif /* _HAS_AUTO_PTR_ETC */template<class _Ty2,class _Dx2,enable_if_t<conjunction_v<negation<is_array<_Ty2>>,is_assignable<_Dx&, _Dx2>,is_convertible<typename unique_ptr<_Ty2, _Dx2>::pointer, pointer>>, int> = 0>unique_ptr& operator=(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept{ // assign by moving _Rightreset(_Right.release());this->get_deleter() = _STD forward<_Dx2>(_Right.get_deleter());return (*this);}//....}