博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STL中uninitialized_copy、uninitialized_fill、uninitialized_fill_n剖析
阅读量:4100 次
发布时间:2019-05-25

本文共 4969 字,大约阅读时间需要 16 分钟。

什么是POD类型?

1、 所有标量类型(基本类型和指针类型)、POD结构类型、POD联合类型、以及这几种类型的数组、const/volatile修饰的版本都是POD类型。

2、 POD结构/联合类型:一个聚合体(包括class),它的非static成员都不是pointer to class member、pointer to class member function、非POD结构、非POD联合,以及这些类型的数组、引用、const/volatile修饰的版本;并且,此聚合体不能有用户自定义的构造函数、析构函数、拷贝构造函数.
3、 POD类型可以具有static成员、成员typedef、嵌套struct/class定义和 成员函数/方法。

以下内容摘自侯捷的《STL源码剖析》

1、uninitialized_copy

        uninitialized_copy() 使 我 们 能 够 将 记 忆 体 的 配 置 与 物 件 的 建 构 行 为 分 离 开 来。如果做为输出目的地的 [result, result+(last-first)) 范围内的每一个迭 代 器 都 指 向 未 初 始 化 区 域 , 则 uninitialized_copy() 会 使 用 copy 
constructor,为身为输入来源之 [first,last) 范围内的每一个对象产生一份复 制品,放进输出范围中。换句话说,针对输入范围内的每一个迭代器 i,此函式会呼叫 construct(&*(result+(i-first)),*i) ,产 生 *i 的 复制 品, 放置 于 输出范围的相对位置上。

        C++ 标准规格书要求 uninitialized_copy() 具有 "commit or rollback" 语意, 意思是要不就「建构出所有必要元素」,要不就(当有任何㆒个 copy constructor 失败时)「不建构任何东西」。

/*	参数说明:		1.迭代器first指向欲初始化空间的起始处		2.迭代器last指向输入端的结束位置(前闭后开区间)		3.迭代器result指向输出端(欲初始化空间)的起始处*/template 
inline ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result){ return __uninitialized_copy(first,last,result,value_type(result));}template
inline ForwardIterator __uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result,T*){ typedef typename __type_traits
::is_POD_type is_POD; return __uninitialized_copy_aux(first,last,result,is_POD());}template
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,__true_type){ return copy(first,last,result);}template
ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,__false_type){ ForwardIterator cur = first; for (;first != last;++first,++cur) { construct(&*cur,*first); } return cur;}//针对char*和wchar_t*两种类型,以最具效率的memmove来执行赋值行为inline char* uninitialized_copy(const char* first,const char* last,char* result){ memmove(result,first,last-first); return result + (last - first);}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);}

2、uninitialized_fill

        uninitialized_fill()也能够使我们将记忆体配置与物件的建构行为分离开来。 如果 [first,last) 范 围内的每个迭代器都指向未初 始化的内存 ,那么 uninitialized_fill() 会在该范围内产生x(上式第三参数)的复制品。换句话说 uninitialized_fill()会针对操作范围内的每个迭代器 i , 呼叫 construct(&*i, x),在 i 所指之处产生 x 的复制品。

        和 uninitialized_copy() 一样,uninitialized_fill() 必须具备 "commit or rollback" 语意,换句话说它要不就产生出所有必要元素,要不就不产生任何元素。 如果有任何一个 copy constructor 丢出异常(exception)uninitialized_fill() 必须能够将已产生之所有元素解构掉。

/*	参数说明:		1.迭代器first指向欲初始化空间的起始处		2.迭代器last指向输入端的结束位置(前闭后开区间)		3.x表示初值*/template 
inline void uninitialized_fill(ForwardIterator first,ForwardIterator last,const T& x){ __uninitialized_fill(first,last,x,value_type(first));}template
inline void __uninitialized_fill(ForwardIterator first,ForwardIterator last,const T& x,T1*){ typedef typename __type_traits
::is_POD_type is_POD; __uninitialized_fill_aux(first,last,x,is_POD());}template
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,__true_type){ fill(first,last,x);}template
void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,__false_type){ ForwardIterator cur = first; for (;cur != last;++cur) { construct(&*cur,x); // 必须一个一个元素地建构,无法批量进行 } return cur;}

3、uninitialized_fill_n

    uninitialized_fill_n() 能够使我们将内存配置与对象建构行为分离开来。 它会为指定范围内的所有元素设定相同的初值。如果 [first, first+n) 范围内的每一个迭代器都指向未初始化的内存,那么 uninitialized_fill_n() 会呼叫 copy constructor,在该范围内产生 x(上式 第三参数)的复制品。也就是说面对 [first,first+n) 范围内的每个迭代器 i, uninitialized_fill_n() 会呼叫 construct(&*i, x),在对应位置处产生 x 的 复制品。

        uninitialized_fill_n() 也具有 "commit or rollback" 语意:要不就产生所有必 要的元素,否则就不产生任 何元素。如果任何一个 copy constructor 丢出异常 (exception),uninitialized_fill_n() 必须解构已产生的所有元素。

/*	参数说明:		1.迭代器first指向欲初始化空间的起始处		2.n表示欲初始化空间的大小		3.x表示初值*/template 
inline ForwardIterator uninitialized_fill_n(ForwardIterator first,size n,const T& x){ // 利用value_type取出first的value type return __uninitialized_fill_n(first,n,x,value_type(first));}template
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first,size n,const T& x,T1*){ typedef typename __type_traits
::is_POD_type is_POD; return __uninitialized_fill_n_aux(first,n,x,is_POD());}//如果是POD类型,籍由函数模板的自变量推导机制得到template
ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first,size n,const T& x,__true_type){ return fill_n(first,n,x);}// 如果不是POD类型ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first,size n,const T& x,__false_type){ ForwardIterator cur = first; for (;n>0;--n,++cur) { construct(&*cur,x); } return cur;}

4、补充construct实现

void construct(pointer p,const T& value){	_construct(p,value);}template 
inline void _construct(T1 *p,const T2& value){ new(p) T1(value); // placement new}

转载地址:http://mwzsi.baihongyu.com/

你可能感兴趣的文章
基于flask的在线笔记共享管理系统【10】(密码加密passlib)
查看>>
操作系统知识点总结(22考研408)【1--绪论】
查看>>
Cygwin模拟器安装及案例使用
查看>>
操作系统模拟实验
查看>>
Spring-Cloud-Finchley | 服务注册与发现 Eureka
查看>>
Spring-Cloud-Finchley | 负载均衡 RestTemplate+Ribbon
查看>>
Spring-Cloud-Finchley | 声明式服务调用 Feign
查看>>
Spring-Cloud-Finchley | 熔断 Hystrix
查看>>
Spring-Cloud-Finchley | 路由网关 Zuul
查看>>
Spring-Cloud-Finchley | 配置中心 Config
查看>>
Kong 网关 | 快速安装与入门
查看>>
PostgreSQL 安装与入门
查看>>
Kong 网关 | Rate Limiting 限流
查看>>
Kong网关 | 「Kong & Prometheus & Grafana」 实时监控
查看>>
Kong 网关 | Service
查看>>
Kong 网关 | Route
查看>>
自媒体的未来
查看>>
写作的好处
查看>>
分布式的冰与火 | 分布式配置中心 Apollo (CentOS安装)
查看>>
Redis | Redis 单机版安装与使用(Linux)
查看>>