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,一经查实,立即删除!

相关文章

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;就像我们用其它语言…

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…

密码学专题 对称加密算法

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

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

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

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;配置…

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)的概念&…

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

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

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没有…

python为什么运行不了_python为什么会环境变量设置不成功

学习python编程&#xff0c;首先要配置好环境变量。本文主要讲解python的环境变量配置&#xff0c;在不同版本下如何安装 Windows 打开Python官方下载网站 x86:表示是32位电脑 x86-64:表示是64位电脑 目前Python版本分为2.x版本和3.x版本。推荐大家使用3.x版本。 设置环境变量&…

STL 源码剖析 heap堆

heap不属于STL容器的组件&#xff0c;属于幕后角色&#xff0c;是priority_queue的助手priority_queue 允许用户以任何次序将任何元素推入容器内&#xff0c;但是取出的时候需要从优先级最高(也就是数值最高)的元素开始取&#xff0c;这种思想是基于heap的函数实现如果使用list…

java 打印星号

代码1 package lesson.l2_for; //6列4行 //****** //****** //****** //****** public class ForDemo8 {public static void main(String[] args) {for (int i1;i<4;i){for (int j 1; j <6 ; j) {System.out.print("*");}System.out.println();}} }代码2 pa…

python从小白到大牛百度云盘_Java从小白到大牛 (关东升著) 中文pdf+mobi版[36MB]

《Java从小白到大牛》是一本Java语言学习立体教程&#xff0c;读者群是零基础小白&#xff0c;通过本书的学习能够成为Java大牛。主要内容包括&#xff1a;Java语法基础、Java编码规范、数据类型、运算符、控制语句、数组、字符串、面向对象基础、继承与多态、抽象类与接口、枚…

java打印九九乘法表

代码1 package lesson.l5_loop; //九九乘法表 //1*11 //2*12 2*24 //3*13 3*26 3*39 //4*14 4*28 4*312 4*416 //5*15 5*210 5*315 5*420 5*525 //6*16 6*212 6*318 6*424 6*530 6*636 //7*17 7*214 7*321 7*428 7*535 7*642 7*749 //8*18 8*216 8*324 8*432 8*540 8*648 8*75…

STL源码剖析 priority_queue

priority_queue是一个拥有权重概念的queue&#xff0c;允许底部加入新的元素&#xff0c;头部删除旧的元素&#xff0c;以及审视元素数值的操作priority_queue带有权重的概念&#xff0c;即元素按照权重进行排列&#xff0c;而不是按照插入队列的顺序进行排序。要求权值高者在前…

python数字1 3怎么表示_Python入门篇之数字

数字类型 数字提供了标量贮存和直接访问。它是不可更改类型&#xff0c;也就是说变更数字的值会生成新的对象。当然&#xff0c;这个过程无论对程序员还是对用户都是透明的&#xff0c;并不会影响软件的开发方式。 Python 支持多种数字类型&#xff1a;整型、长整型、布尔型、双…

STL源码剖析 slist单向链表概述

概述 SGI STL的list是一个双向链表&#xff0c;单向链表是slist&#xff0c;其不在标准规格之内单向和双向链表的区别在于&#xff0c;单向链表的迭代器是单向的 Forward Iterator&#xff0c;双向链表的迭代器属于双向的Bidirectional Iterator。因此很多功能都被受限但是单向…