std::unique_ptr源码中构造函数的偏特化。_Unique_ptr_enable_default_t

先看一个:

	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);}//....}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/477756.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue生命周期详解

目录 1.beforeCreate2.created3.beforeMount4.mounted5.beforeUpdate6.updated7.beforeUnmount&#xff08;beforeDestroy&#xff09;8.unmounted&#xff08;destroyed&#xff09; 1.beforeCreate 分析 beforeCreate执行时Vue实例还没有被创建&#xff0c;data和methods也…

MySQL底层概述—1.InnoDB内存结构

大纲 1.InnoDB引擎架构 2.Buffer Pool 3.Page管理机制之Page页分类 4.Page管理机制之Page页管理 5.Change Buffer 6.Log Buffer 1.InnoDB引擎架构 (1)InnoDB引擎架构图 (2)InnoDB内存结构 (1)InnoDB引擎架构图 下面是InnoDB引擎架构图&#xff0c;主要分为内存结构和磁…

【力扣算法题】双指针-战场上的矛与盾的组合(移动零)(快乐数)

前言 &#x1f31f;&#x1f31f;本期讲解关于力扣算法两道双指针题目解析~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么…

第三十九篇 ShuffleNet V1、V2模型解析

摘要 ShuffleNet V1 ShuffleNet V1是由旷视科技&#xff08;Megvii&#xff0c;又称Face&#xff09;在2017年底提出的一种轻量级卷积神经网络架构。该网络专为移动设备和边缘计算环境设计&#xff0c;旨在以较低的计算资源实现高效的图像分类和其他计算机视觉任务。 特点与…

Springboot系列之:创建Springboot项目,Springboot整合MyBatis-plus

Springboot系列之&#xff1a;创建Springboot项目&#xff0c;Springboot整合MyBatis-plus 一、快速创建Spring boot项目二、项目完整目录三、pom.xml四、application.yaml五、实体类六、mapper七、IService接口八、Service实现类九、配置类十、枚举十一、增删改查测试类十二、…

C++:用红黑树封装map与set-1

文章目录 前言一、STL源码分析二、红黑树的构建三、map与set整体框架的搭建与解析四、如何取出进行比较&#xff1f;1. met与set的数据是不同的2. 取出数据进行比较1&#xff09;问题发现2&#xff09;仿函数解决 五、封装插入六、迭代器的实现1. operator* 与operator->2. …

Perforce《2024游戏技术现状报告》Part3:生成式AI、版本控制、CI/CD等游戏技术的未来趋势与应用

游戏开发者一直处于创新前沿。他们的实践、工具和技术受到各行各业的广泛关注&#xff0c;正在改变着组织进行数字创作的方式。 近期&#xff0c;Perforce发布了《2024游戏技术现状报告》&#xff0c;通过收集来自游戏、媒体与娱乐、汽车和制造业等高增长行业的从业者、管理人…

4-SpringCloud整合服务间的调用即负载均衡

springcloud目录&#xff1a; 1.Spring Cloud简介 2.SpringCloud整合eureka注册中心 3.SpringCloud整合服务注册 4.SpringCloud整合服务间的调用即负载均衡 5.SpringCloud整合Feign调用 6.SpringCloud整合config配置中心 7.SpringCloud整合zuul路由网关 我们复制一个yqx-user服…

Elasticsearch客户端在和集群连接时,如何选择特定的节点执行请求的?

大家好&#xff0c;我是锋哥。今天分享关于【Elasticsearch客户端在和集群连接时&#xff0c;如何选择特定的节点执行请求的&#xff1f;】面试题。希望对大家有帮助&#xff1b; Elasticsearch客户端在和集群连接时&#xff0c;如何选择特定的节点执行请求的&#xff1f; 100…

深入浅出,快速安装并了解汇编语言

1.什么是汇编语言 了解汇编语言需要先从了解机器语言开始&#xff0c;在计算机发展的初期阶段&#xff0c;机器语言是计算机直接理解和执行的二进制代码语言&#xff0c;其核心特点包括直接执行性、资源高效性、学习难度大以及平台依赖性。它主要由指令码构成&#xff0c;这些…

2.2_3 纠错编码—海明码

目录 1、海明码的纠错过程 2、海明距离 3、确认检验码位数 4、确定校验码和数据的位置 5、求出校验码的值 6、检错并纠错 方法一 方法二 1、海明码的纠错过程 2、海明距离 两个合法编码(码字)的对应比特取值不同的比特数称为这两个码字的海明距离(码距)&#xff0c;一…

1992-2021年 各省市县经过矫正的夜间灯光数据(GNLD、VIIRS)区域汇总:省份、城市、区县面板数据

1992-2021年 各省市县经过矫正的夜间灯光数据&#xff08;GNLD、VIIRS&#xff09;区域汇总&#xff1a;省份、城市、区县面板数据 .r.rar https://download.csdn.net/download/2401_84585615/90001905 从1992年至2021年&#xff0c;中国各省份、城市及区县的夜间灯光数据经过…

微信小程序上传微信官方审核流程(1)

1&#xff0c;打开微信开发者工具 2&#xff0c;微信开发者工具右上角有一个上传按钮&#xff0c;点击上传按钮 3&#xff0c;点击完上传按钮会弹出一个上传成功的提示&#xff0c;点击提示框中的确定按钮 4&#xff0c;点击完确定按钮后会显示填写版本好和项目备注 5&#x…

快速获取镜像包的方法

1、当我们需要在无网络的环境中&#xff0c;在Docker环境中安装某个镜像时&#xff0c;需要先下载这个镜像包后&#xff0c;再上传 2、下面以在minio为例 在有网络的电脑中使用使用命令下载 docker pull minio/minio将下载好的tar包保存到指定的目录下 save -o /home/cl/app…

11 —— 打包模式的应用

需求&#xff1a;在开发模式下想让webpack使用style-loader进行css样式的处理&#xff1b;让它把css代码内嵌在js中&#xff1b;在生产模式下提取css代码 —— 判断当前运行命令时所在的环境 方案&#xff1a;借助cross-env全局软件包&#xff0c;设置参数区分打包运行环境 …

docker容器化部署springboot项目

前言 docker安装 下载官网 选择自己的系统 然后安装文档内给的命令按顺序执行即可。设置仓库&#xff0c;安装docker. 一、更换镜像源 一般情况下,docker原本自带的镜像网站不一定连的上,就很容易导致下载镜像失败,因此需要换源. 创建/etc/docker/daemon.json并填入数据…

2024深育杯misc2

题目描述&#xff1a;攻击者远程服务器监听所用的端口是( )&#xff1f;请提交flag&#xff0c;例如端口号为80&#xff0c;则提交Sangfor{80} 附件解压打开是一个raw文件 用volatility3工具查看ip链接信息

UI自动化测试中公认最佳的设计模式-POM

一、概念 什么是POM&#xff1f; POM是PageObjectModule&#xff08;页面对象模式&#xff09;的缩写&#xff0c;其目的是为了Web UI测试创建对象库。在这种模式下&#xff0c;应用涉及的每一个页面应该定义为一个单独的类。类中应该包含此页面上的页面元素对象和处理这些元…

L14.【LeetCode笔记】返回倒数第k个节点

目录 1.题目 2.分析 思路 代码 提交结果 1.题目 面试题 02.02. 返回倒数第 k 个节点 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 注意&#xff1a;本题相对原题稍作改动 示例&#xff1a; 输入&#xff1a; 1->2->3->4->5 和 …

linux-进程间通信

进程的通信是两个或多个进程实现数据的交互&#xff0c;让不同的进程看到同一份资源&#xff0c;而这份资源是由操作系统创建管理的。如果让其中一个进程来提供的话会破坏该进程的独立性&#xff0c;因为这个进程内部的数据可以被其他进程看到&#xff0c;那这个独立性就遭到了…