copy
不论是对客端程序或对STL内部而言,copy()都是一个常常被调用的函数。由于copy进行的是复制操作,而复制操作不外乎应用assignment operator或者copy construct(copy 算法用的是前者),但是某些元素型别拥有的是trivial assignment operator,因此,如果能够使用内存直接复制行为(例如C标准函数memmove或者memcopy), 便能节省大量时间。为此,SGI STL的copy算法用尽各种办法,包括函数重载(function overloading)、型别特性(type traits)、偏特化(partial specialization)等编程技巧,无所不用其极地加强效率。下图表示了copy()操作的脉络。稍后配合源码进行说明;
copy算法可将输入区间[first,last)内的元素复制到输出区间[result, result+(last-first))内,也就是说,它会执行赋值操作*result = *first,*(result+i)=*(first+i)直到first+i达到last。最终返回一个迭代器result + (last-first).copy对其template参数所要求的条件非常宽松。其输入区间只需要是InputIterator构成即可,输出区间只需要是OutputIterator构成即可。这意味着你可以使用copy算法,将任何容器的任何一段区间的内容,复制到任何容器的任何一段区间上。
对于每个从0到last-first的整数n,copy执行赋值操作*(result+n) = *(first+n).赋值操作是向前操作的。
如果输入区间和输出区间完全没有重叠,当然毫无问题,否则便需特别注意。如下图所示:
第二种情况当result位于first与last当中时,可能会出现错误。
从稍后即将显示的源码可知,copy元素时一一进行元素的赋值操作,如果输出区间的起点位于输入区间内,copy算法便(可能)会在输入区间的(某些)元素尚未被复制之前,就覆盖其值,导致错误的结果。在这里我们一再使用可能这个字眼,是因为,如故宫copy算法根据其所接收迭代器的特性决定调用memmove()来执行任务,就不会造成上述错误,因为memmove(),会考虑重叠的情况再进行处理,保证不会出现值还没被拷贝就被覆盖的情况。
下面的测试代码,是对上图copy的测试
#include <iostream>
#include <algorithm>
#include <deque>
#include <list>
using namespace std;
template <class T>
struct display {
void operator() (const T& x) { c