STL源码剖析 数值算法 copy 算法
生活随笔
收集整理的這篇文章主要介紹了
STL源码剖析 数值算法 copy 算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- copy復制操作,其操作通過使用assignment operator 。針對使用trivial assignment operator的元素型別可以直接使用內存直接復制行為(使用C函數 memove或者memcpy)節約時間。
- 還可以通過函數重載(function overloading)、型別特性(type traits)、偏特化(partial specialization)等技巧進一步強化效率。
- copy函數將[first,last) 內的元素復制到區間[result,result+(last-first))內
- 返回迭代器指向的是??result+(last-first)
- 輸入區間使用?InputIterator,輸出區間使用?OutputIterator
- 注意事項:1,result位于[first , last)之內的時候也就是輸出區間的起頭與輸入區間重疊,不能使用copy;如果輸出區間的尾端和輸入區間重疊,就可以使用
- 上述第二種情況可能出現錯誤,是可能。如果輸出區間的起點位于輸入區間內部,copy算法可能會在輸入區間的(某些)元素尚未復制之前就將其覆蓋其值,導致錯誤
- 如果copy算法根據其所接收的迭代器特性 決定使用memmove()來執行任務,就不會出現問題,因為memmove 會將整個輸入區間的內容復制下來就不會出現覆蓋的危險
- 使用vector代替上述的deque進行測試復制結果是正確的,因為vector的迭代器其實就是個原生指針
- copy更改的是迭代器所指向的對象,并不是修改迭代器本身,他會為區間內的元素賦予新的數值,但不是產生新的元素,也不會改變迭代器的個數。即,copy不能用來將元素插入到空的容器中
- 使用copy算法配合序列容器的insert_iterator?
?
#include <iostream> //std::cout//完全泛化的版本 template <class InputIterator,class OutputIterator> inline OutputIterator copy(InputIterator first,InputIterator last,OutputIterator result){return __copy_dispatch<InputIterator ,OutputIterator>()(first,last,result); }//兩個重載函數 針對原生指針(視為一種特殊的迭代器)const char* 和 const wchar_t 進行內存的直接拷貝操作 //特殊版本1 重載形式 const char * inline char* copy(const char* first,const char* last,char* result){std::memmove(result,first,last - first);return result + (last - first); }//特殊版本2 重載形式 const wchar_t * inline wchar_t* copy(const wchar_t* first,const wchar_t* last,wchar_t* result){std::memmove(result,first,sizeof(wchar_t)*(last - first));return result + (last - first); }//copy泛化版本調用了一個 __copy_dispatch函數,這個函數有一個完全泛化版本和兩個偏特化版本 //完全泛化版本 //__copy_dispatch完全泛化版本根據迭代器的種類不同,調用了不同的__copy(),是因為不同種類的迭代器使用的循環條件不同,有快有慢 template <class InputIterator,class OutputIterator> struct __copy_dispatch{OutputIterator operator()(InputIterator first,InputIterator last,OutputIterator result){return __copy(first,last,result,iterator_category(first));} };//InputIterator 版本 template <class InputIterator,class OutputIterator> inline OutputIterator __copy(InputIterator first,InputIterator last,OutputIterator result,std::input_iterator_tag){//通過迭代器的等同與否 決定循環是否繼續 速度很慢while(first!=last){*result = *first; //assignment operator++first;++result;}return result; }//RandomAccessIterator 版本 template <class RandomAccessIterator,class OutputIterator> inline OutputIterator __copy(RandomAccessIterator first,RandomAccessIterator last,OutputIterator result,std::random_access_iterator_tag){//劃分新的函數 為了讓其余地方可以使用return __copy_d(first,last,result, distance_type(first)); }template <class RandomAccessIterator,class OutputIterator,class Distance> inline OutputIterator __copy_d(RandomAccessIterator first,RandomAccessIterator last,OutputIterator result,Distance*){//使用n決定循環的執行次數 速度快Distance n = last - first;while (n>0){*result = *first; //assignment operator++result;++first;n--;}return result; }//偏特化版本1 兩個參數的型別都是T* 指針 template<class T> struct __copy_dispatch<T*,T*> {T* operator()(T* first,T* last,T* result){typedef typename __type_traits<T>::has_trival_assignment_operator t;return __copy_t(first,last,result,t());} };//偏特化版本2 第一個參數是constT*指針形式 第二個參數是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_trival_assignment_operator t;return __copy_t(first,last,result,t());} };//在上述偏特化版本指定參數類型為T*和const T*只針的前提下進一步探測 //探測指針所指之物是否具備trivial assignment operator (平凡賦值操作符) //SGI STL通過使用__type_traits<>編程技巧 和 增加一層間接性 來區分不同的 __copy_t()//適用于指針所指對象具備 trivial assignment operator template <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 operator template <class T> inline T* __copy_t(const T* first,const T* last,T* result,__false_type){//原生指針是一種 RandomAccessIterator 所以交給 __copy_d()完成return __copy_d(first,last,result,(std::ptrdiff_t)0); }?
總結
以上是生活随笔為你收集整理的STL源码剖析 数值算法 copy 算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 员工意外险在哪里买
- 下一篇: Linux加密框架 crypto 算法模