當(dāng)前位置:
首頁(yè) >
STL源码剖析 数值算法 copy 算法
發(fā)布時(shí)間:2023/12/13
30
豆豆
生活随笔
收集整理的這篇文章主要介紹了
STL源码剖析 数值算法 copy 算法
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
- copy復(fù)制操作,其操作通過(guò)使用assignment operator 。針對(duì)使用trivial assignment operator的元素型別可以直接使用內(nèi)存直接復(fù)制行為(使用C函數(shù) memove或者memcpy)節(jié)約時(shí)間。
- 還可以通過(guò)函數(shù)重載(function overloading)、型別特性(type traits)、偏特化(partial specialization)等技巧進(jìn)一步強(qiáng)化效率。
- copy函數(shù)將[first,last) 內(nèi)的元素復(fù)制到區(qū)間[result,result+(last-first))內(nèi)
- 返回迭代器指向的是??result+(last-first)
- 輸入?yún)^(qū)間使用?InputIterator,輸出區(qū)間使用?OutputIterator
- 注意事項(xiàng):1,result位于[first , last)之內(nèi)的時(shí)候也就是輸出區(qū)間的起頭與輸入?yún)^(qū)間重疊,不能使用copy;如果輸出區(qū)間的尾端和輸入?yún)^(qū)間重疊,就可以使用
- 上述第二種情況可能出現(xiàn)錯(cuò)誤,是可能。如果輸出區(qū)間的起點(diǎn)位于輸入?yún)^(qū)間內(nèi)部,copy算法可能會(huì)在輸入?yún)^(qū)間的(某些)元素尚未復(fù)制之前就將其覆蓋其值,導(dǎo)致錯(cuò)誤
- 如果copy算法根據(jù)其所接收的迭代器特性 決定使用memmove()來(lái)執(zhí)行任務(wù),就不會(huì)出現(xiàn)問(wèn)題,因?yàn)閙emmove 會(huì)將整個(gè)輸入?yún)^(qū)間的內(nèi)容復(fù)制下來(lái)就不會(huì)出現(xiàn)覆蓋的危險(xiǎn)
- 使用vector代替上述的deque進(jìn)行測(cè)試復(fù)制結(jié)果是正確的,因?yàn)関ector的迭代器其實(shí)就是個(gè)原生指針
- copy更改的是迭代器所指向的對(duì)象,并不是修改迭代器本身,他會(huì)為區(qū)間內(nèi)的元素賦予新的數(shù)值,但不是產(chǎn)生新的元素,也不會(huì)改變迭代器的個(gè)數(shù)。即,copy不能用來(lái)將元素插入到空的容器中
- 使用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); }//兩個(gè)重載函數(shù) 針對(duì)原生指針(視為一種特殊的迭代器)const char* 和 const wchar_t 進(jìn)行內(nèi)存的直接拷貝操作 //特殊版本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泛化版本調(diào)用了一個(gè) __copy_dispatch函數(shù),這個(gè)函數(shù)有一個(gè)完全泛化版本和兩個(gè)偏特化版本 //完全泛化版本 //__copy_dispatch完全泛化版本根據(jù)迭代器的種類不同,調(diào)用了不同的__copy(),是因?yàn)椴煌N類的迭代器使用的循環(huán)條件不同,有快有慢 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){//通過(guò)迭代器的等同與否 決定循環(huán)是否繼續(xù) 速度很慢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){//劃分新的函數(shù) 為了讓其余地方可以使用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決定循環(huán)的執(zhí)行次數(shù) 速度快Distance n = last - first;while (n>0){*result = *first; //assignment operator++result;++first;n--;}return result; }//偏特化版本1 兩個(gè)參數(shù)的型別都是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 第一個(gè)參數(shù)是constT*指針形式 第二個(gè)參數(shù)是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());} };//在上述偏特化版本指定參數(shù)類型為T*和const T*只針的前提下進(jìn)一步探測(cè) //探測(cè)指針?biāo)钢锸欠窬邆鋞rivial assignment operator (平凡賦值操作符) //SGI STL通過(guò)使用__type_traits<>編程技巧 和 增加一層間接性 來(lái)區(qū)分不同的 __copy_t()//適用于指針?biāo)笇?duì)象具備 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); }//適用于指針?biāo)笇?duì)象具備 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); }?
總結(jié)
以上是生活随笔為你收集整理的STL源码剖析 数值算法 copy 算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 员工意外险在哪里买
- 下一篇: Linux加密框架 crypto 算法模