STL 源代码剖析 算法 stl_numeric.h -- copy
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
copy
//唯一对外接口
/*--------------------------------------------------------------------------------------
* 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
}
STL 源代码剖析 算法 stl_numeric.h -- copy的更多相关文章
- STL 源代码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partial_sort / partial_sort_copy ------------- ...
- STL 源代码剖析 算法 stl_algo.h -- search
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- random_shuffle
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie random_shuffle ------------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- partition
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partition ------------------------------------ ...
- STL 源代码剖析 算法 stl_algo.h -- inplace_merge
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) ----------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- next_permutation
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie next_permutation ----------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- nth_element
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie nth_element ---------------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- lower_bound
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) ------------------------- ...
- STL 源代码剖析 算法 stl_algo.h -- merge sort
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...
随机推荐
- JavaScript判断横屏/竖屏
/判断手机横竖屏状态: function hengshuping(){ if(window.orientation==180||window.orientation==0){ ...
- MSSQL - 自增1的标识列一次增长了1000
@情若天_RunUp: 1. Open "SQL Server Configuration Manager"2. Click "SQL Server Services&q ...
- redhat6.3 jfreechar中文乱码解决途径
最近使用到jfreechar的项目,在转移到linux上面时出现中文乱码(中文被显示为框框),网上查了一些资料,结合自身系统的特性,总结了一种安装字体的方式.在说字体安装之前首先上个测试的代码吧:we ...
- gcc manual
$ gcc --helpUsage: gcc [options] file...Options: -pass-exit-codes Exit with highest error c ...
- HDU--杭电--4502--吉哥系列故事——临时工计划--背包--01背包
吉哥系列故事——临时工计划 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) To ...
- Swift - 操作表(UIActionSheel)的用法,也叫底部警告框
1,下面创建一个操作表(或叫底部警告框)并弹出显示 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class ViewController: UIViewC ...
- Android自定义shape的使用
MainActivity如下: package cn.testshape; import android.os.Bundle; import android.app.Activity; /** * D ...
- 计算VMT的长度
function GetVirtualMethodCount(AClass: TClass): Integer; begin Result := (PInteger(Integer(AClass) + ...
- C语言信号学习笔记
在C语言中,对于错误有很多处理方式.然而,今天学习了信号处理,感觉这种处理方式十分灵活,特此记录. 关于信号处理的函数包含于头文件<signal.h>中.所谓的信号,多指出乎程序员意料的行 ...
- Dom生成Xml和解析Xml
xml这样的文件格式在非常多时候都是非常适合我们用来存取数据的,所以利用程序来生成xml文件和解析xml文件就显得比較重要了.在dom中是把每个元素都看做是一个节点Node的,全部页面上的属性.元素等 ...