C++ STL标准库 其他部分

目录

 

一、一个万用的 Hash Function

二、tuple 用例

三、type traits

3.1 type traits 的应用

3.2 type traits 的实现

四、cout

五、moveable

5.1 moveable 的实现

5.1 moveable 的测试


一、一个万用的 Hash Function

一般实现哈希函数的三种方式:普通函数 、 hash 函数对象  、hash() 函数的偏特化重写

 

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

C++2.0 的新语法 — 标号1中,<typename... Type> 表示可以接收任意多个模板参数

<typename... Type>借用不定量的参数拆解开来并利用递归解决。

  • hash_val() 函数(非标准库,其算法思想由用户实现,可以利用这种思想做出万能的 hash function),用来解决一个包含多个不同类型成员的类对象的哈希编码问题。其参数列表可以自定义个数,需要几个就放几个。
  • n个参数被调整成 seed,n之后再次调用 hash_val第二版本 参数为 seed,1,n-1 ,用这个被分割出来的 1 去改 seed,剩下的 n-1 又会再次分割成 1,n-2,继续由这个 1 去改 seed,迭代直到被分成一个一个的,最后变成 seed+1 的 调用方法3解决。
  • 改 seed :hash_combine,调用每个基本类型的 hash_function 再经过一系列加值与移位(本质上也是经验算法,借用了黄金比例值 1.618 的概念)。改完之后 seed 就是 hashcode。算出的 hashcode 是没有 %n 之前的值。

测试:

  

实现 hash() 对 Mystring 做偏特化版本。可以引用已有的偏特化或者利用上面的 hash_val 算法的思想。

二、tuple 用例

可以指定任意的元素,而且元素可以是任意的类型集合成为一个对象。

tuple 的使用

  • 创造与初始化一个 tuple 的几种方式:tuple<类型名>(初始化列表)make_tuple() 方法
  • get<0>(对象名) 取 tuple 中的第一个元素,取出的元素可以进行单独复制。
  • 两个不同类型的 tuple 甚至可以互相比较大小,可以互相赋值。 
  • tie(i1,f1,s1) = t3; 将 t3 中的所有元素拿出来附着到 三个变量中去。 

  

typename... Tail 说明有很多个 type            Tail... 有很多个Tail

class tuple<Head,Tail...> : private tuple<Tail...>  继承少一个模板参数下的自己(父类数据在内存分布的较上方),实现分解递归。

tuple 开放了两个函数 head() 和 tail() 可以外部使用。head 得到当前头数据,tail 获得除了头数据之外的整体。

三、type traits

旧版本的 C++,泛化的模板中,所有 回答算法的 关于类型的 5 个 typedef 即 5 个问题:默认构造、拷贝构造、复制运算。。。函数 是否为 trival (不重要)的,默认的答案都是 false ,即“重要的”。同时使用了 特化,对一些基本类型的这些问题的做出了 “不重要” 的回答。而对一些用户自定义的类或类型,就得由用户自己去写偏特化来回答这些问题。 

3.1 type traits 的应用

C++ 新标准下,不再需要用户自己去写偏特化,可以通过提供的 traits 对类型直接提问

type_traits_output()

几个问题:

  1. 一个类需不需要写析构函数?                     只要类成员有指针就必须要写,如果没有指针多半不必写。
  2. 一个类需不需要写虚析构函数?                 一个类如果要准备作为 base class 的话,才需要写虚析构函数。

&&  move 构造函数

3.2 type traits 的实现

用模板对类型做操作

  1. 先做 remove_cv() 去掉 const 和 volatile(多线程关键字) 这这些无关的类型性质的影响。
  2. 丢给 helper,泛化情况下的所有类型回答 false, 符合偏特化的特定类型时才回答 true。
template<typename _Tp>
    struct remove_const
    { typedef _Tp    type; }                  //泛化,直接返回类型


template<typename _Tp>
    struct remove_const<_Tp const>
    { typedef _Tp    type; }                  //特化 const 时候的情况,返回去掉const 后的类型

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

四、cout

 cout 本质是 派生于 ostream 类(_IO_ostream_withassign)的一个对象,

  • extern 表示在本文件之外,也能被使用。
  • cout 类方法中重载了许多数据类型的输出方法。
  • 未在 cout 重载范围内的,就要由用户自己在定义的类中提供输出运算符的重载。

五、moveable

5.1 moveable 的实现

  • move ctor 操作,只拷贝了指针的值(参数初始化列表中实现)。不用做深层次的内存分配,即浅拷贝。 
  • 对于次数很多的拷贝动作,当涉及指针指向的元素的构造与赋值时,move 操作会极大地节省了时间。
  • 采用 insert 操作调用构造函数,编译器(意识到要insert 的 buffer 之后不会再被使用了,所以才这样选择)就会自动选择 move 版本拷贝构造或者 非move 版本拷贝构造。

5.1 moveable 的测试

copy 即深拷贝的时间消耗很多         

move copy 浅拷贝 与 swap 的消耗时间很少。用 move 拷贝的条件就是 拷贝之后 原来的东西不再使用。

M c11(c1);深拷贝时,c1不是临时对象,所以编译器不能自动选择 move copy ,要使用的话只能显示指定 M c12(std::move(c1));浅拷贝,使用结束后 c1 就作废了。

string类 带有 moveable 的特性。

猜你喜欢

转载自blog.csdn.net/SimonxxSun/article/details/86318157
今日推荐