C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲

一个万用的哈希函数

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第1张图片

函数对象作为哈希函数,设置不定序容器时,规定<容器中的元素,hash 函数对象名>,相比普通函数简便太多。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第2张图片

左边把3个特化版本的哈希函数算出的哈希码加起来。“太天真”,换成左边的版本。

typename...   代表着任意多参数。(可变化模板variadic templates)hash_val先调用1,再调用2,2就再调用4,seed就变了,然后再次调用自己,不断调用自己,直到变成3的参数类型,调用3(n个分为1+n-1,然后再取一个和1合并再变成1+n-2,直到变为1+1)。

hash_combine(seed,val),每一个算出hashcode,再与种子做一些奇奇怪怪的运算,总之越分散越好。

0x9e3779b9:黄金比例的观念,百度就完了。

第三种形式:针对自己的类型写一个特化版本

新版中的基本类型都有特化的哈希函数

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第3张图片

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第4张图片

 Tuple用例

允许声明一个结构体时(不是struct),可以的指定要任意的元素,元素是任意的类型。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第5张图片

0代表拿第0个元素,1代表第一个元素,2代表第2个元素。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第6张图片

继承它自己,class tuple :private tuple继承了尾的部分,头的部分就声明出一个变量。

tail得到的是父类的起点。去掉头的部分。

type traits

询问该类型的默认构造器,拷贝构造器,析构器,赋值运算符重要么?默认重要,即__false_type。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第7张图片

比如问:__type_traits::has_trivial_destructor;

使用的方式:

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第8张图片

类要不要写析构函数:只要它带指针就要写,不带多半不用写。

一个类要写不写虚析构函数:当它作为一个基类时。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第9张图片

 Zoo(Zoo&&)=default;//搬移构造函数

type traits实现

先去掉const,volatile(多线程关键字)特性,再丢给helper,泛化默认false,符合偏特化的特定类型才回答true。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第10张图片

 像 is_class,is_union,is_enum,is_pod 的这些高级功能的实现都是编译器在编译过程中整理出来的数据,所分析得到的结果。这些东西不在C++标准库中。

cout

它本质是ostream的一个对象。extern表示这里的变量可以被外界使用,这个文件之外的也可以看到它。

  • cout 类方法中重载了许多数据类型的输出方法。
  • 未在 cout 重载范围内的,就要由用户自己在定义的类中提供输出运算符的重载。

movable

movable元素对于各容器速度效能的影响

CCtor这里代表拷贝构造器,MCtor代表搬移构造器。

vector开始空间不够,扩充增长了,所以空间变化为原先的2倍,因此次数是7194383。

后4个容器因为结构不同,不需要像vector那样空间增长,因此差别不会那么大。

insert在红黑树和散列表中也可以找到一个合适的位置

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第11张图片

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第12张图片

movable的实现

copy版本和move版本就只在灰色那部分,即&&,move是浅拷贝,拷贝指针而已,换了个指针指过来,把原指针删掉,而copy就是真的有分配。

对于次数很多的拷贝动作,当涉及指针指向的元素的构造与赋值时,move 操作会极大地节省了时间。

采用 insert 操作调用构造函数,编译器(意识到要insert 的 buffer 之后不会再被使用了,所以才这样选择)就会自动选择 move 版本拷贝构造或者 非move 版本拷贝构造。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第13张图片

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第14张图片 

moveable的测试

move不够安全,因为一定要确认原来的不会再使用,才可以用move。

临时对象是一个右值。

C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲_第15张图片

move copy 浅拷贝 与 swap 的消耗时间很少。 

string类 带有 moveable 的特性。

你可能感兴趣的:(C++ STL源码剖析与泛型编程(侯捷)(九) 第四讲)