STL源码剖析 __type_traits

  • traits编程 弥补了C++本身的不足
  • STL只对迭代器进行规范制定出了iterator_traits,SGI在此基础上进一步扩展,产生了__type_traits
  • 双下划线的含义是这个是SGI内部使用的东西,不属于STL标准
  • iterator_traits 负责萃取迭代器的特性
  • __type_traits负责萃取型别特性。比如是否具备non-trivial default ctor? non-trivial copy ctor?non-trivial assignment operator?non-trivial dtor? 如果答案是否定的,就可以对这个型别进行构造、析构、拷贝、赋值等操作时,采取最有效率的措施.
  • 比如 根本不调用身居高位的constructor、destructor,直接进行内存层面上的操作,比如malloc()、memcpy()等等,进一步提高效率
  • __type_traits 允许针对不同的型别属性在编译时期完成函数的派送指定。这对于撰写模板很有帮助,比如对一个元素型别未知的数组进行copy操作的时候,如果事先知道元素的型别是否有一个trivial copy constructor,就可以帮助函数确定是否可以使用memcpy() 或者 memmove()
  • 根据iterator_traits的经验,程序应该采用如下的方式使用__type_traits  其中T代表任意的型别
__type_traits<T>::has_trivial_default_constructor
__type_traits<T>::has_trivial_copy_constructor
__type_traits<T>::has_trivial_assignment_operator
__type_traits<T>::has_trivial_destructor
__type_traits<T>::is_POD_type
  • 上述的公式 响应真或者假,从而函数决定采用什么样的处理策略。但是不仅仅是一个bool数值,而应该是一个具备真假性质的对象。因为需要利用它的响应结果来进行参数的推导,而编译器只会对具备class object形式的参数才会进行类型的推导
  • 因此,上述公式应该返回的是 如下的形式,这两个空白的classes没有任何的成员,不会带来额外的负担,但是能表明真假,满足需求
struct __true_type{};
struct __false_type{};
  • 为了满足上述的式子,__type_traits必须定义一些typedef ,其类型不是__true_type,就是__false_type
  • 下面是SGI的做法
struct __true_type{};
struct __false_type{};template <class type>
struct __type_traits{/** 不要移除这个成员,他通知"有能力自动将__type_traits特化"的编译器说,现在的* 这个__type_traits是特殊的,确保万一编译器也使用一个__type_traits而其实* 与此处定义并没有任何关联的模板的时候,不出现错误*/typedef __true_type this_dummy_member_must_be_first;/** 遵守以下的约定,因为编译器有可能自动为各个型别产生专属的__type_traits* 特化版本*    1,可以重新排列以下成员的次序*    2,不可以删除以下成员*    3,绝对不可以将以下成员重新命名,但是没有改变编译器中对应的名称*    4,新加入的成员视为一般成员,除非你在编译器中加上适当的支持*/typedef __false_type has_trivial_default_constructor;typedef __false_type has_trivial_copy_constructor;typedef __false_type has_trivial_assignment_operator;typedef __false_type has_trivial_destructor;typedef __false_type is_POD_type;
};
  • 将所有的内嵌型别都定义为__false_type,默认是最为保守的数值。
  • 随后可以根据每一个标量类型设计适当的__type_traits的特化版本

特化版本

  • 以下针对C++基本型别char \ signed char \ unsigned char \ short \ unsigned short \ int  \ unsigned int \ long  \ unsigned long \ float \ double \ long double 提供了特化版本,每一个的成员数值都是true_type,即这些型别都可以采用最快速的方式(例如 memcpy) 进行拷贝 或者 赋值操作
  • SGI STL<stl_config.h> 将以下出现的__STL_TEMPLATE_NULL d定义为template<> ,是所谓的class template explicit specialization
template<>
struct __type_traits<char>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<signed char>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned char>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<short>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned short>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<int>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned int>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<long>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned long>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<float>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<double>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<long double>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<class T>
struct __type_traits<T*>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};
  • 以上内容均将__STL_TEMPLATE_NULL 替换为 template <> 

  • type_traits在SGI STL中使用很广泛 例如:uninitialized_fill_n()全局函数、destroy()函数、copy()函数 (STL源码剖析110页),他们的思想都是一样的,分为泛型和偏特化两种模式,进行切换
  • 一个class什么时候应该有自己的 non-trivial default ctor? non-trivial copy ctor?non-trivial assignment operator?non-trivial dtor?简单的判断准则是,如果这个类内含指针成员,并且对它进行内存动态配置,那么这个类就需要自己实现 non trivial XXX,即上述内容

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

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

相关文章

java 学生成绩

题目 对学生成绩大于60分的&#xff0c;输出“合格”。低于60分的&#xff0c;输出“不合格” 代码 使用/除法简化代码 package l1_switch_case;import java.util.Scanner;public class SwitchDemo2 {public static void main(String[] args) {Scanner scanner new Scanne…

STL源码剖析 序列式容器|Vector

容器的概观和分类 array 数组 、list 链表、tree树 、stack堆栈、queue队列、hash table散列表、set集合、map映射表根据数据在容器中的排列顺序&#xff0c;将上述数据结构分为序列式和关联式两种类型SGI STL使用内缩方式来表达基层和衍生层之间的关系衍生不是派生&#xff0…

ansible 修改文件变量_Ansible Playbook中的变量与引用

Ansible是一个系列文章&#xff0c;我会尽量以通俗易懂、诙谐幽默的总结方式给大家呈现这些枯燥的知识点&#xff0c;让学习变的有趣一些。Ansible自动化运维前言前面有说到使用playbook来搞一些复杂的功能&#xff0c;我们使用YAML来写playbook&#xff0c;就像我们用其它语言…

java 判断日期为第几天

题目1 编写程序&#xff1a;从键盘上输入2019年的“month”和“day”&#xff0c;要求通过程序 输出输入的日期为2019年的第几天。 代码1 从12月往下加日期数 package l1_switch_case; import java.util.Scanner; public class SwitchDemo4 {public static void main(Strin…

STL源码剖析 list概述

目录 list的节点(node) list迭代器 list 的构造和内存管理 list 的元素操作 list相较于vector连续的线性空间就显得很复杂&#xff0c;他的存储空间是不连续的&#xff0c;好处是每次插入和删除一个元素的时候&#xff0c;只需要配置或者释放一个元素的空间 插入和删除十分的…

vsftp不允许切换到其它目录_IntelliJ IDEA如何对project的目录进行筛选显示?

如果你的项目很庞大&#xff0c;同一个功能用到的各种文件散落在多个文件夹&#xff0c;开发时切换不便&#xff0c;可以利用scope功能&#xff0c;只显示该功能用到的文件&#xff0c;让project列表十分清爽&#xff0c;提高开发效率。本文使用的IDEA版本为2020.1。1、打开sco…

java 年份对应的中国生肖

题目 编写一个程序&#xff0c;为一个给定的年份找出其对应的中国生肖。 中国的生肖基于12年一个周期&#xff0c; 每年用一个动物代表&#xff1a; rat、ox、tiger、rabbit、dragon、snake、horse、sheep、monkey、 rooster、dog、pig。 提示&#xff1a;2019年&#xff1a;猪…

密码学专题 对称加密算法

一般来说&#xff0c;使用OpenSSL对称加密算法有两种方式&#xff0c;一种是使用API函数的方式&#xff0c;一种是使用OpenSSL提供的对称加密算法指令方式。本书将介绍对称加密算法的指令方式OpenSSL的对称加密算法指令主要用来对数据进行加密和解密处理&#xff0c;输入输出的…

网络防火墙单向和双向_单向晶闸管与双向晶闸管之间的不同之处

晶闸管是回一个可以控导点开关&#xff0c;能以弱电去控制强电的各种电路。晶闸管常用于整流&#xff0c;调压&#xff0c;交直流变化&#xff0c;开关&#xff0c;调光等控制电路中。具有提交小&#xff0c;重量轻&#xff0c;耐压高&#xff0c;容量大&#xff0c;效率高&…

java 遍历100以内的偶数,偶数的和,偶数的个数

题目 遍历100以内的偶数&#xff0c;偶数的和&#xff0c;偶数的个数 代码 package l2_for; /*遍历100以内的偶数&#xff0c;偶数的和&#xff0c;偶数的个数*/ public class ForDemo1 {public static void main(String[] args) {//方法1&#xff1a;int sum1 0,count10;f…

python版本切换_怎么切换python版本

展开全部 &#xff08;1&#xff09;分别安2113装 python-2.7.12.amd64.msi python-3.5.2-amd64.exe &#xff08;python官网下载的&#xff09; 顺序无所谓&#xff08;为5261了看着4102方便&#xff0c;我把安装路径修改统一了1653&#xff09; &#xff08;2&#xff09;配置…

java 打印

题目 编写程序从1循环到150&#xff0c;并在每行打印一个值&#xff0c;另外在每个3的倍数行 上打印出“foo”,在每个5的倍数行上打印“biz”,在每个7的倍数行上打印 输出“baz”。 代码 package l2_for;/** 编写程序从1循环到150&#xff0c;并在每行打印一个值&#xff0c…

react.lazy 路由懒加载_Vue面试题: 如何实现路由懒加载?

非懒加载import List from /components/list.vue const router new VueRouter({routes: [{ path: /list, component: List }] })方案一(常用)const List () > import(/components/list.vue) const router new VueRouter({routes: [{ path: /list, component: List }] })方…

STL源码剖析 deque双端队列 概述

vector是单向开口的连续线性空间&#xff0c;deque是一种双向开口的连续线性空间。deque可以在头尾两端分别进行元素的插入和删除操作vector和deque的差异 1&#xff0c;deque允许常数时间内对于头端元素进行插入和删除操作2&#xff0c;deque没有所谓容量(capacity)的概念&…

java 最大公约数和最小公倍数

题目 题目&#xff1a;输入两个正整数m和n&#xff0c;求其最大公约数和最小公倍数。 比如&#xff1a;12和20的最大公约数是4&#xff0c;最小公倍数是60。 说明&#xff1a;break关键字的使用 代码一 package l2_for; //题目&#xff1a;输入两个正整数m和n&#xff0c;求…

python的自带数据集_Python的Sklearn库中的数据集

一、Sklearn介绍 scikit-learn是Python语言开发的机器学习库&#xff0c;一般简称为sklearn&#xff0c;目前算是通用机器学习算法库中实现得比较完善的库了。其完善之处不仅在于实现的算法多&#xff0c;还包括大量详尽的文档和示例。其文档写得通俗易懂&#xff0c;完全可以当…

STL源码剖析 stack 栈 概述->(使用deque双端队列 / list链表)作为stack的底层容器

Stack是一种先进后出的数据结构&#xff0c;他只有一个出口stack允许 新增元素、移除元素、取得最顶端的元素&#xff0c;但是无法获得stack的内部数据&#xff0c;因此satck没有遍历行为Stack定义的完整列表 (双端队列作为Stack的底层容器) 将deque作为Stack的底部结构&#…

java 三位数的水仙花数

代码 package l2_for;public class ForDemo6 {public static void main(String[] args) {for (int i 100; i <999 ; i) {int i1i/1%10;int i2i/10%10;int i3i/100%10;if (i(int)(Math.pow(i1,3)Math.pow(i2,3)Math.pow(i3,3))){System.out.print(i"\t");}}} }

python怎么实现图像去噪_基于深度卷积神经网络和跳跃连接的图像去噪和超分辨...

Image Restoration Using Very Deep Convolutional Encoder-Decoder Networks with Symmetric Skip Connections作者&#xff1a;Xiao-Jiao Mao、Chunhua Shen等本文提出了一个深度的全卷积编码-解码框架来解决去噪和超分辨之类的图像修复问题。网络由多层的卷积和反卷积组成&a…

STL源码剖析 queue队列概述

queue是一种先进先出的数据结构&#xff0c;他有两个出口允许新增元素&#xff08;从最底端 加入元素&#xff09;、移除元素&#xff08;从最顶端删除元素&#xff09;&#xff0c;除了对于顶端和底端元素进行操作之外&#xff0c;没有办法可以获取queue的其他元素即queue没有…