STL标准模板库中的copy算法,整体设计比较复杂,使用起来也比较麻烦,因为copy函数为了强化效率可以说是无所不用其极。用到的编程技巧有函数重载,型别特化, 偏特化等技巧。所以STL库中的copy函数体现了泛化的思想
copy函数的整体架构:
(一)泛化的copy
inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
{
return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result);
}
(1)利用迭代器的指向来拷贝数据,但是因为迭代器不同的类型,所以采用偏特化来针对不同类型的迭代器进行不同的操作。
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》如果是inputiterataor输入迭代器,因为其只有前向++,所以用first!=last来遍历
template <class InputIterator, class OutputIterator>
inline OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator result,
input_iterator_tag)
{
for ( ; first != last; ++result, ++first)
*result = *first;
return result;
}
《2》如果是任意类型的迭代器,则通过调用__copy_d()函数
template <class RandomAccessIterator, class OutputIterator>
inline OutputIterator __copy(RandomAccessIterator first, RandomAccessIterator last,
OutputIterator result, 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*)
{
for (Distance n = last - first; n > 0; --n, ++result, ++first)
*result = *first;
return result;
}
(2)拷贝数据如果数据型别是用户自定义的型别,而不是系统内置型别,那么就要通过萃取机制观测所要拷贝的数据是自定义的还是内置的,萃取机制自己以前的博客写过。了解了拷贝的数据型别就能够利用最有效率的方法去拷贝数据。如果是内置的型别则可以通过调用memmove()内存底层的操作速度块。但是如果是用户自定义的数据型别,则要通过拷贝构造函数来进行拷贝操作。
这个是针对内置型别的数据的拷贝的实现
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);
}
这个是针对用户自定义型别数据的拷贝实现
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,函数原型如下,可以看到传入的数据类型为char
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,函数原型如下,可以看到传入的数据类型为wchar_t
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);
}