【STL源码剖析读书笔记】【第6章】算法之copy算法

来源:互联网 发布:网络问卷调查怎么总结 编辑:程序博客网 时间:2024/05/21 22:46

        由于copy进行的是复制操作,而复制操作不外乎用assignment operator或copy constructor(copy算法用的是前者),但是某些元素型别拥有的是trivial assginment operator,因此,如果能够使用内存直接复制行为(例如C标准函数memmove或memcpy),便能够节省大量时间。为此,SGI STL的copy算法用尽各种办法,包括函数重载、型别特性、偏特化等编程技巧,无所不用其极地加强效率。如下图所示:


注意:

1)  copy只是将输出区间内的元素赋予新值,不会产生新的元素,所以copy不能直接用来将元素插入空容器中.

2)  copy的输出区间的起点如果位于输入区间内,可能会使copy算法出错。

STL copy函数源码如下:

//SGI STL的copy算法运用函数重载、型别特性、偏特化等编程技巧,无所不用其极地加强效率//完全泛化版本template <class InputIterator, class OutputIterator>inline OutputIterator copy(InputIterator first, InputIterator last,OutputIterator result){return __copy_dispatch<InputIterator, OutputIterator>()(first, last, result);}//全特化版本一,底层用memmove,节省时间inline char* copy(const char* first, const char* last, char* result) {memmove(result, first, last - first);return result + (last - first);}//全特化版本二,底层用memmove,节省时间inline wchar_t* copy(const wchar_t* first, const wchar_t* last,wchar_t* result) {memmove(result, first, sizeof(wchar_t)* (last - first));return result + (last - first);}//copy()函数的完全泛化版本调用了__copy_dispatch()函数,它有一个完全泛化版本和两个偏特化版本//完全泛化版本template <class InputIterator, class OutputIterator>struct __copy_dispatch{OutputIterator operator()(InputIterator first, InputIterator last,OutputIterator result) {return __copy(first, last, result, iterator_category(first));}};//偏特化版本一,两个参数都是T*形式,根据指针所指对象是否具有trivial assignment operator调用不同的__copy_t()函数template <class T>struct __copy_dispatch<T*, T*>{T* operator()(T* first, T* last, T* result) {typedef typename __type_traits<T>::has_trivial_assignment_operator t;return __copy_t(first, last, result, t());}};//偏特化版本二,第一个参数是const T*形式,第二个参数是T*形式,根据指针所指对象是否具有trivial assignment operator调用不同的__copy_t()函数template <class T>struct __copy_dispatch<const T*, T*>{T* operator()(const T* first, const T* last, T* result) {typedef typename __type_traits<T>::has_trivial_assignment_operator t;return __copy_t(first, last, result, t());}};//__copy_dispatch()函数的完全泛化版本调用了__copy()函数,它有两个版本//InputIterator版本,以迭代器是否等同判断循环是否进行,速度慢template <class InputIterator, class OutputIterator>inline OutputIterator __copy(InputIterator first, InputIterator last,OutputIterator result, input_iterator_tag){for (; first != last; ++result, ++first)*result = *first;return result;}//RandomIterator版本,调用__copy_d()函数template <class RandomAccessIterator, class OutputIterator>inline OutputIterator__copy(RandomAccessIterator first, RandomAccessIterator last,OutputIterator result, random_access_iterator_tag){return __copy_d(first, last, result, distance_type(first));}//以n决定循环次数,速度快template <class RandomAccessIterator, class OutputIterator, class Distance>inline OutputIterator__copy_d(RandomAccessIterator first, RandomAccessIterator last,OutputIterator result, Distance*){for (Distance n = last - first; n > 0; --n, ++result, ++first)*result = *first;return result;}//适用于指针所指对象具备trivial assignment operatortemplate <class T>inline T* __copy_t(const T* first, const T* last, T* result, __true_type) {memmove(result, first, sizeof(T)* (last - first));return result + (last - first);}//适用于指针所指对象具备non-trivial assignment operatortemplate <class T>inline T* __copy_t(const T* first, const T* last, T* result, __false_type) {return __copy_d(first, last, result, (ptrdiff_t*)0);}

   

0 0
原创粉丝点击