STL中uninitialized_copy、uninitialized_fill、uninitialized_fill_n剖析

2023-12-29 14:38

本文主要是介绍STL中uninitialized_copy、uninitialized_fill、uninitialized_fill_n剖析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是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 <class InputIterator ,class ForwardIterator>
inline ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result)
{return __uninitialized_copy(first,last,result,value_type(result));
}template <class InputIterator ,class ForwardIterator,class T>
inline ForwardIterator __uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result,T*)
{typedef typename __type_traits<T>::is_POD_type is_POD;return __uninitialized_copy_aux(first,last,result,is_POD());
}template <class InputIterator ,class ForwardIterator,class T>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,__true_type)
{return copy(first,last,result);
}template <class InputIterator ,class ForwardIterator,class T>
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 <class ForwardIterator,class T>
inline void uninitialized_fill(ForwardIterator first,ForwardIterator last,const T& x)
{__uninitialized_fill(first,last,x,value_type(first));
}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());
}template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,__true_type)
{fill(first,last,x);
}template <class ForwardIterator,class T>
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 <class ForwardIterator,class size,class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first,size n,const T& x)
{// 利用value_type取出first的value typereturn __uninitialized_fill_n(first,n,x,value_type(first));
}template <class ForwardIterator,class size,class T,class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first,size n,const T& x,T1*)
{typedef typename __type_traits<T1>::is_POD_type is_POD;return __uninitialized_fill_n_aux(first,n,x,is_POD());
}//如果是POD类型,籍由函数模板的自变量推导机制得到
template <class ForwardIterator,class size,class T>
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 <class T1,class T2>
inline void _construct(T1 *p,const T2& value)
{new(p) T1(value);	// placement new
}




这篇关于STL中uninitialized_copy、uninitialized_fill、uninitialized_fill_n剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/549739

相关文章

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验

C++ STL 适配器

系列文章目录 模板特例化,偏特化,左右值引用 https://blog.csdn.net/surfaceyan/article/details/126794013 C++ STL 关联容器 https://blog.csdn.net/surfaceyan/article/details/127414434 C++ STL 序列式容器(二) https://blog.csdn.net/surfac

C++ STL关联容器Set与集合论入门

1. 简介 Set(集合)属于关联式容器,也是STL中最实用的容器,关联式容器依据特定的排序准则,自动为其元素排序。Set集合的底层使用一颗红黑树,其属于一种非线性的数据结构,每一次插入数据都会自动进行排序,注意,不是需要排序时再排序,而是每一次插入数据的时候其都会自动进行排序。因此,Set中的元素总是顺序的。 Set的性质有:数据自动进行排序且数据唯一,是一种集合元素,允许进行数学上的集合相

深度剖析AI情感陪伴类产品及典型应用 Character.ai

前段时间AI圈内C.AI的受够风波可谓是让大家都丈二摸不着头脑,连C.AI这种行业top应用都要找谋生方法了!投资人摸不着头脑,用户们更摸不着头脑。在这之前断断续续玩了一下这款产品,这次也是乘着这个风波,除了了解一下为什么这么厉害的创始人 Noam Shazeer 也要另寻他路,以及产品本身的发展阶段和情况! 什么是Character.ai? Character.ai官网:https://

stl的sort和手写快排的运行效率哪个比较高?

STL的sort必然要比你自己写的快排要快,因为你自己手写一个这么复杂的sort,那就太闲了。STL的sort是尽量让复杂度维持在O(N log N)的,因此就有了各种的Hybrid sort algorithm。 题主你提到的先quicksort到一定深度之后就转为heapsort,这种是introsort。 每种STL实现使用的算法各有不同,GNU Standard C++ Lib

最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)

文章目录 一、自动配置概念二、半自动配置(误~🙏🙏)三、源码分析1、验证DispatcherServlet的自动配置2、源码分析入口@SpringBootApplication3、@SpringBootConfiguration的@Configuration4、@EnableAutoConfiguration的@AutoConfigurationPackage和@Import5、Auto

C语言深度剖析--不定期更新的第四弹

哈哈哈哈哈哈,今天一天两更! void关键字 void关键字不能用来定义变量,原因是void本身就被编译器解释为空类型,编译器强制地不允许定义变量 定义变量的本质是:开辟空间 而void 作为空类型,理论上不应该开辟空间(针对编译器而言),即使开辟了空间,也只是作为一个占位符看待(针对Linux来说) 所以,既然无法开辟空间,也无法作为正常变量使用,既然无法使用,干脆编译器不让它编译变

Java CAS 原理剖析

在Java并发中,我们最初接触的应该就是synchronized关键字了,但是synchronized属于重量级锁,很多时候会引起性能问题,volatile也是个不错的选择,但是volatile不能保证原子性,只能在某些场合下使用。   像synchronized这种独占锁属于悲观锁,它是在假设一定会发生冲突的,那么加锁恰好有用,除此之外,还有乐观锁,乐观锁的含义就是假设没有发生冲突,那么我正