源码阅读笔记 - 2 std::vector (2) 关于Allocator Aware Container特性
所有的STL容器,都保存一个或默认,或由用户提供的allocator的实例,用来提供对象内存分配和构造的方法(除了std::array),这样的容器,被称作Allocator Aware Container。早期的STL,设计的尚不完善,各种实现之间不能相互兼容,这一点在侯捷的《STL源码剖析》中有提到:有些STL的实现无法兼容标准的allocator实现,因为他们使用了更为复杂的二级配置器。而在我昨天阅读完vector和其处理allocator拷贝、移动和交换问题的源码后,发现这种问题在如今的STL中已经不再存在,allocator和容器的标准本身提供了选项,用于更加复杂的分配器的拷贝操作。
每一个Allocator Aware Container在拷贝构造(copy constuction)的时候,都会调用被拷贝对象的std::allocator_traits<TAllocator>::select_on_container_copy_construction()函数,这是一个静态函数,会通过编译时重载决议,按情况拷贝,或者直接返回被拷贝对象的allocator。
函数内部通过调用allocator的成员select_on_container_copy_construction()函数,如果没有,就直接返回容器本体。
同时,容器的设计者也应该在容器拷贝的时候要么调用静态的propagate_on_container_copy_assignment,要么直接调用成员propagate_on_container_copy_assignemnt,获取被拷贝容器的allocator副本,避免出现直接拷贝容器的bug。
每一个std::allocator_traits<Tallocator>都拥有三个别名类型:propagate_on_container_copy_assignment, propagate_on_container_move_assignment 和 propagate_on_container_swap,他们都是true_type或false_type的别名,这三个属性除非用户自定义,否则默认是false_type,也即allocator在容器拷贝、移动或交换的时候不能直接进行allocator所分配的内存的所有权的转移
容器在移动赋值(move assignment)的时候需要考虑如下情况,来正确操作容器的allocator:
- propagate_on_container_move_assignemnt 为 true_type
- propagate_on_container_move_assignemnt 为 false_type,但两个allocator相等
- propagete_on_container_move_assignment 为 false_type,两个allocator不等
第{1}和{2, 3}能通过编译时重载决议区分,而{2},{3}需要运行时通过if判断。
第一种情况下,lhs需要先用他自己的allocator释放掉它自己分配的东西,然后rhs的allocator的所有权转移(move),最后是memory的所有权从rhs转移到lhs。
第二种情况下,可以重复第一种情况,但是allocator本身不需要交换所有权
第三种情况,无法执行内存级别的移动,只能进行对象级别的移动
对于移动构造,直接把allocator move过来,然后转移memory的所有权。
对于拷贝赋值(copy assignment),需要运行时判断容器的propagate_on_copy_assignement trait,如果为true,并且两个容器不相等,那么lhs的容器应该先析构所有内存,再拷贝allocator,最后执行对象的拷贝。
有了上面的设计,使用多级分配器的容器间的拷贝变得有可能了,如果有人想要给每一个allocator使用一个独立的内存池,那么显然内存池之间的对象所有权不是随随便便拷贝个指针就能转移的,这时也许需要把三个tag都设置为false,让allocator的operator==重载不直接返回true,使得资源的转移按照自己期望的方式进行。如果自定义allocator内存池可以直接进行已分配对象的内存池间所有权传递,那么propagate_on_container_move_assignemnt可以为true_type,然后在两个内存池allocator的移动构造函数里做好所有权转移的事情;如果自定义allocator内存池不能转移已分配对象的所有权,那就把propagate_on_container_move_assignemnt设为false,operator==中进行两个内存池的比较,这时候回到上面说的{2, 3}情况,操作依然保证移动的正确性。
源码阅读笔记 - 2 std::vector (2) 关于Allocator Aware Container特性的更多相关文章
- 源码阅读笔记 - 2 std::vector (1)
vector的源码真是太长了,今天用了一个下午和一个晚上看和注释了前面的一千行左右 p.s.博客园的代码高亮真是太垃圾, 如果想要阅读带注释的源码,推荐粘贴到VS2015里,然后按ctrl+z取消自动 ...
- 源码阅读笔记 - 3 std::string 与 Short String Optimization
众所周知,大部分情况下,操作一个自动(栈)变量的速度是比操作一个堆上的值的速度快的.然而,栈数组的大小是在编译时确定的(不要说 C99 的VLA,那货的 sizeof 是运行时计算的),但是堆数组的大 ...
- 源码阅读笔记 - 1 MSVC2015中的std::sort
大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...
- mxnet源码阅读笔记之include
写在前面 mxnet代码的规范性比Caffe2要好,看起来核心代码量也小很多,但由于对dmlc其它库的依赖太强,代码的独立性并不好.依赖的第三方库包括: cub dlpack dmlc-core go ...
- CI框架源码阅读笔记5 基准测试 BenchMark.php
上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功 ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- CI框架源码阅读笔记2 一切的入口 index.php
上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...
- Three.js源码阅读笔记-5
Core::Ray 该类用来表示空间中的“射线”,主要用来进行碰撞检测. THREE.Ray = function ( origin, direction ) { this.origin = ( or ...
随机推荐
- winform在设置控件enabled=false后,无法更改控件字体颜色的问题
项目界面设计的时候,发现在设置button的enabled=false后,原本设计的字体颜色跟预设的不一样,查了一些资料后,在网上看到这样一段代码: [System.Runtime.InteropSe ...
- Win10/UWP开发-Ink墨迹书写
在UWP开发中,微软提供了一个新型的InkCanvas控件用来让用户能书写墨迹,在新版的Edga浏览器中微软自己也用到了该控件使用户很方便的可以在web上做笔记. InkCanvas控件使用很简单,从 ...
- 第三个Sprint总结
工作进展:项目基本已经完成 工作状况:
- java高级规范之一
一.不允许使用汉语拼音命名 不规范示例: public void zengjiaYongHu{}//拼音方法名称 规范示例: public void addUser(){} 解析:应该使用国际化语音, ...
- Day21_IO第三天
1.IO体系总图 2.字符流体系图 记忆路线:输入输出流前面加File和Buffered,这就记住6个了,还剩两个转换流名字比较特殊,需要着重记一下(转换流:字节和字符的组合,所以起名字叫InputS ...
- Java的Package和Classpath
Package 在Java中,Package是用来包含一系相关实例的集合.这些相关联的实例包括:类.接口.异常.错误以及枚举. Package主要有一些的几点作用: Package可以处理名字冲突,在 ...
- The Non-Inverting Amplifier Output Resistance by Adrian S. Nastase [ Copied ]
Source Address: http://masteringelectronicsdesign.com/the-non-inverting-amplifier-output-resistance/ ...
- FMS 4中multicast脚本的小修正
FMS 4中multicast脚本的小修正 http://help.adobe.com/en_US/flashmediaserver/devguide/WS7812b00092aae0dc-2829d ...
- Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xm
mybatis解析xml配置文件出现异常: org.apache.ibatis.exceptions.PersistenceException: Error building SqlSession. ...
- leetcode 187. Repeated DNA Sequences 求重复的DNA串 ---------- java
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...