STL之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 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值