STL源码剖析 内存基本处理工具 初始化空间的五个函数

  • 初始化空间的五个函数
  • 构造函数 construct()
  • 析构函数 destroy()
  • 剩余三个底层函数 和 高层函数之间的对应关系如下
  • uninitialized_copy()  对应 copy()
  • uninitialized_fill()  对应 fill()
  • uninitialized_fill_n()  对应 fill_n()
  • 使用<memory>使用上述三个底层函数

uninitialized_copy()

template<class InputIterator,class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result);
  • uninitialized_copy() 将内存的配置和对象的构造行为分离开来
  • 如果指向的输出区域[result ,result+(last - first)] 内的每一个迭代器都指向的是未经初始化的区域,那么uninitialized_copy()会使用copy constructor,给身为输入来源的[first , last] 范围内的每一个对象产生一个复制品,放到输出范围内
  • 针对输入范围内的每一个迭代器i 使用construct(&*(result + (i-first)),*i) 产生*i的复制品,放置到输出范围的相对位置上

容器的全局间构造函数 通过两个步骤完成

  • 配置内存块  足以包含范围内的所有元素
  • 使用uninitialized_copy()在这个范围上构造元素

注意事项

  • 原子性;commit or rollback
  • 要不给所有元素都全部执行构造函数,要不不构造任何东西,必须析构已经产生的所有元素
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就会有效
//如果是POD型别 执行的流程就会跳转到以下函数,这个是通过function template的参数推导机制得到的
template<class InputIterator,class ForwardIterator>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,true_type){return copy(first,last,result);//调用STL算法 copy()
}
//如果不是POD型别 执行的流程就会转向以下函数  这个是通过function template的参数推导机制得到的
template<class InputIterator,class ForwardIterator>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,false_type){ForwardIterator cur = result;//为了简化 省略了异常处理for(; first!=last;++first,++cur){Chy::_allocate(&*cur,*first);}return cur;
}//函数的逻辑是
//首先萃取出 迭代器first的value type,然后判断这个型别是否是POD类型
template<class InputIterator,class ForwardIterator,class T>
inline ForwardIterator __uninitizlized_copy(ForwardIterator first,ForwardIterator last,ForwardIterator result,T*){//以下使用的是__type_traits<T1>::is_POD_type is _PODtypedef typename __type_traits<T>::is_POD_type is_POD;return (__uninitialized_copy_aux(first,last,result,is_POD()));
}/** 迭代器first指向的是 输入端的起始位置* 迭代器last指向的是 输入端的结束位置* 迭代器result指向的是 输出端的(初始化)的起始位置*/
template<class InputIterator,class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result){}//针对 char* 和wchar*两种型别 采用最有效率的做法 memmove(直接移动内存内存执行复制的行为)
//偏特化设计
//针对const char*的特化版本inline char* uninitialized_copy(const char* first,const char* last,char* result){memmove(result,first,last-first);return result+(last - first);
}//针对const wchar_t *的特化版本
inline wchar_t* uninitialized_copy(const wchar_t* first,const wchar_t* last,wchar_t* result){memmove(result,first,sizeof(wchar_t)*(last - first));return result + (last - first);
}

uninitialized_fill()

template<class ForwardIterator,class T>
ForwardIterator uninitialized_fill(ForwardIterator first,ForwardIterator last,const T&x);
  • uninitialized_fill() 将内存的配置和对象的构造行为分离开来
  • 如果指向的输出区域[first,last] 内的每一个迭代器都指向的是未经初始化的区域,那么uninitialized_fill()会在这个范围内产生x(上述第三个参数的复制品)
  • 即uninitialized_fill()会针对[first,last]范围内的每个迭代器i 调用construct(&*i,x),在i所指定的地方产生i的复制品。

注意事项

  • 原子性;commit or rollback
  • 要不给所有元素都全部执行构造函数,要不不构造任何东西,必须析构已经产生的所有元素
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就会有效
//如果是POD型别 执行的流程就会跳转到以下函数,这个是通过function template的参数推导机制得到的
template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,true_type){fill(first,last,x);//调用STL算法 fill()
}
//如果不是POD型别 执行的流程就会转向以下函数  这个是通过function template的参数推导机制得到的
template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,false_type){ForwardIterator cur = first;//为了简化 省略了异常处理for(;cur != last;++cur){Chy::_construct(&*cur,x);}
}template<class ForwardIterator,class T,class T1>
inline void __uninitialized_fill(ForwardIterator first,ForwardIterator last,const T&x,T1*){typedef typename __type_traits<T1>::is_POD_type is_POD;__uninitialized_fill_aux(first,last,x,is_POD());
}/** 迭代器first指向输出端 (欲初始化空间) 起始处* 迭代器last指向的输出端 (欲初始化空间) 结尾处 前闭后开区间* x 表示初始数值*/
template<class ForwardIterator,class T>
ForwardIterator uninitialized_fill(ForwardIterator first,ForwardIterator last,const T&x){__uninitialized_fill(first,last,x,value_type(first));
}

uninitialized_fill_n()

template<class ForwardIterator,class Size,class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,const T&x);
  • uninitialized_fill_n() 将内存的配置和对象的构造行为分离开来
  • 如果指向的输出区域[first,first+n] 内的每一个迭代器都指向的是未经初始化的区域,那么uninitialized_fill()会在这个范围内产生x(上述第三个参数的复制品)
  • 即uninitialized_fill()会针对[first,last]范围内的每个迭代器i 调用construct(&*i,x),在i所指定的地方产生i的复制品。
  • 原子性;commit or rollback
  • 要不给所有元素都全部执行构造函数,要不不构造任何东西,必须析构已经产生的所有元素

补充

  • POD类型是指 Plain Old Data,也就是标量类型或者传统的C struct型别
  • POD类型 必然具备trivial ctor/dtor/copy/assignment函数
  • 因此对于POD型别采用最有效率的初值填写手法,对于non POD型别采取最保险安全的做法
//如果是copy construction 等同于assignment而且destructor 是 trivial以下就会有效
//如果是POD型别 执行的流程就会跳转到以下函数,这个是通过function template的参数推导机制得到的
template<class ForwardIterator,class Size,class T>
inline ForwardIterator __uninitizlized_fill_n_aux(ForwardIterator first,Size n,const T&x){return fill_n(first,n,x); //交给高阶函数执行
}//如果不是POD型别 执行的流程就会转向以下函数  这个是通过function template的参数推导机制得到的
template<class ForwardIterator,class Size,class T>
inline ForwardIterator __uninitizlized_fill_n_aux(ForwardIterator first,Size n,const T&x,false_type){ForwardIterator cur = first;//为了简化 省略了异常处理for( ; n>0 ; --n,++cur){Chy::_allocate(&*cur,x);}return cur;
}//函数的逻辑是
//首先萃取出 迭代器first的value type,然后判断这个型别是否是POD类型
template<class ForwardIterator,class Size,class T,class T1>
inline ForwardIterator __uninitizlized_fill_n(ForwardIterator first,Size n,const T&x,T1*){//以下使用的是__type_traits<T1>::is_POD_type is _PODtypedef typename __type_traits<T1>::is_POD_type is_POD;return __uninitizlized_fill_n_aux(first,n,x,is_POD());
}template<class ForwardIterator,class Size,class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,const T&x){return __uninitizlized_fill_n(first,n,x,value_type(first));//使用value_type()判断first的value type
}

参考链接

  • C++ STL __type_traits解析 - 知乎

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

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

相关文章

单基因gsea_筛到5分的核心基因以后你可以怎么做?

这一次我们从一些已经发表的文章拆解&#xff0c;我们来看看&#xff0c;你找到了一个核心基因以后&#xff0c;你可以怎么做呢&#xff1f;我们就不说那么多废话了&#xff0c;直接用几篇文章的解读来带着大家领会一下如何去进行下一步的分析。Case1&#xff1a;预后标志物免疫…

STL源码剖析 迭代器的概念和traits编程技法

迭代器&#xff1a;依序巡防某个聚合物(容器)所含的各个元素&#xff0c;但是不需要暴露这个聚合物的内部表述方式核心思想&#xff1a;将容器和算法分开&#xff0c;彼此独立设计容器和算法的泛型化&#xff0c;均可以使用模板&#xff0c;使用迭代器连接容器和算法例子 templ…

STL源码剖析 5中迭代器型别

最常使用的5种迭代器的型别 为 value_type、difference_type、pointer、reference、iterator_category。如果想要自己开发的容器和STL进行适配&#xff0c;就需要定义上述5种类型 iteraor_traits 必须针对传入的型别为 pointer 或者 pointer-to-const设计偏特化版本 template &…

加载tf模型 正确率很低_深度学习模型训练全流程!

↑↑↑关注后"星标"Datawhale每日干货 & 每月组队学习&#xff0c;不错过Datawhale干货 作者&#xff1a;黄星源、奉现&#xff0c;Datawhale优秀学习者本文从构建数据验证集、模型训练、模型加载和模型调参四个部分对深度学习中模型训练的全流程进行讲解。一个成…

Python学习17 Turtle库绘图

学习网址&#xff1a;https://docs.python.org/zh-cn/3/library/turtle.html Turtle库 Turtle库是Python语言中一个很流行的绘制图像的函数库&#xff0c;一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff08;画布中心&#xff09;&#xff0c;(0,0)位置开…

android ros 节点编写_嵌入式的我们为什么要学ROS

前言本来是要写一篇STM32移植ROS的一个小lib库&#xff0c;ROS一般都是需要跑在Linux上的&#xff0c;STM32使用就是当成一个ROS通讯的小节点&#xff0c;但是写文章时间不够&#xff0c;所以就简单做一篇ROS的介绍文章&#xff0c;分享给嵌入式的小伙伴们。ROS现在在机器人领域…

STL源码剖析 __type_traits

traits编程 弥补了C本身的不足STL只对迭代器进行规范制定出了iterator_traits&#xff0c;SGI在此基础上进一步扩展&#xff0c;产生了__type_traits双下划线的含义是这个是SGI内部使用的东西&#xff0c;不属于STL标准iterator_traits 负责萃取迭代器的特性__type_traits负责萃…

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版本。 设置环境变量&…