STL之copy函式
阿新 • • 發佈:2019-02-17
//唯一對外介面 /*-------------------------------------------------------------------------------------- * copy 函式及其過載形式 */ //完全泛化版本。 template<class InputIterator, class OutputIterator> // ? 這裡的 InputIterator 和 OutputIterator 都只是名稱而已,哪裡確保了它們真的至少是 InputIterator 和 OutputIterator ? inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result){ // 不明白為什麼要用 function object 實現,用普通的 function 實現不行嗎? // 因為 function object 可以偏特化 ? 但普通的 function 也可以過載呀 // 難道因為通過 function object 實現的偏特化是編譯時多型,比 function 過載的執行時多型要好 ? return __copy_dispatch<InputIterator, OutputIterator>() (first, last, result); } //針對原生指標(可視為一種特殊的迭代器) const char * 和 const wchar_t *, 進行記憶體直接拷貝操作 //特殊版本[1] 過載形式 inline char *copy(const char* first, const char *last, char *result){ memmove(result, first, last - first); return result + (last - first); //為什麼要返回這樣的迭代器呢? } //特殊版本[2] 過載形式 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_dispatch 及其偏特化版本 */ //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)); } }; //下面的兩個偏特化版本的引數為原生指標形式 //偏特化版本[1],兩個引數都是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()); } }; //偏特化版本[2],第一個引數是 const T*指標形式,第二引數是 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 函式 */ // 下面的 InputIterator 版本、 RandomAccessIter 版本 中的 InputIterator 和 RandomAccessIter 都只是名稱而已,編譯器怎麼知道具體化哪個函式版本? ? // --> 有個 input_iterator_tag 來確定迭代器的型別,從而使編譯器能夠知道該具體化哪個函式的版本 //InputIterator 版本 template<class InputIterator, class OutputIterator> inline OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator result, input_iterator_tag){ //如果只是 InputIterator 的話,以迭代器贊同與否,決定迴圈是否繼續、速度慢 for( ; first != last; ++result, ++first) *result = *first; return result; } // RandomAccessIter 版本 template<class RandomAccessIter, class OutputIterator> inline OutputIterator __copy(RandomAccessIter first, RandomAccessIter last, OutputIterator result, random_access_iterator_tag){ // 其他地方可能也會用到 __copy_d return __copy_d(first, last, result, distance_type(first)); } template<class RandomAccessIter, class OutputIterator, class Distance> inline OutputIterator __copy_d(RandomAccessIter first, RandomAccessIter last, OutputIterator result, Distance *){ // 以 n 決定迴圈的執行次數。速度快 for(Distance n = last - first; n > 0; --n, ++result, ++first) *result = *first; return result; } /*-------------------------------------------------------------------------------------- * 偏特化版本使用的 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){ return __copy_d(first, last, result, (ptrdiff_t *) 0); // 轉而呼叫 __copy_d }