天天看点

STL算法 — copy

为了效率,copy算法可谓无所不用其极,通过分析copy算法能够体会STL的精妙。

首先是三个对外接口:

如果传入的迭代器是字符型的原生指针,那么直接使用底层的memmove拷贝,效率是非常高的,但如果是普通的迭代器,则需要进一步分析了。再看看__copy_dispatch函数,此函数又兵分三路,包括一个泛化版本和两个偏特化版本:

首先分析泛化版本。如果迭代器仍为普通迭代器,则调用泛化版本。它要根据迭代器的类型(输入或随机)调用不同的函数:

由于输入迭代器的移动只能靠operator++,所以采用逐个赋值。如果是随机迭代器,则继续往下调用:

这里之所以要再单独定义一个函数是因为下述的原生指针版本也可能会调用它。由于是随机迭代器,所以它是以n是否大于0为循环判断条件。相比于输入迭代器的判断条件first != last,这个版本显然效率是要高一些的。这就充分利用了迭代器之间的区别尽可能的进行效率优化。

下面分析两个特化版本。当迭代器为原生指针时,调用__copy_t,它的第三个参数是用来判断指针所指类型是否真的需要用复制操作符来一个个复制(也就是判断是trivial还是non-trivial),这种判断工作就交给了类型萃取器__type_traits来完成。

根据是否需要单独复制可以把__copy_t分成两个版本:

trivial版本就很容易了,直接memmove,不需要做过多的复制动作。而non-trivial版本的拷贝则需要逐一进行。由于原生指针属于随机迭代器,所以它可以退而求其次,调用刚才介绍的__copy_d函数。

至此,一个既支持泛化,又具有极高效率的copy函数诞生了!

参考:

《STL源码剖析》 P314.