空间配置讲完了,那如何在分配的空间上进行数据操作呢?前面讲过了construct()和destroy(),另外还有三个填充类函数,其实际定义于<stl_uninitialized>:
一、uninitialized_copy:区间拷贝
// 内存的配置与对象的构造行为分离开来。
template <class _InputIter, class _ForwardIter>
inline _ForwardIter
uninitialized_copy(_InputIter __first, _InputIter __last,
_ForwardIter __result)
{
return __uninitialized_copy(__first, __last, __result,
__VALUE_TYPE(__result));
}
简单来说就是首先得到__result的 value_type(如是是否POD类型,判断是否含有non-trivial 函数),进而判断是调用construct() 还是 直接调用memmove()或copy() ;然后,就是把 [__first,__last)这个区间上的数据,挨个复制到目标容器上。
可以看出__result 这个迭代器有两个功能:指示目标容器的起点;指示迭代器所指元素的类型。
以下是这个函数的进一步转调:
// 这个函数用来过渡的,这种技法在类型推导中比较常见
template <class _InputIter, class _ForwardIter, class _Tp>
inline _ForwardIter
__uninitialized_copy(_InputIter __first, _InputIter __last,
_ForwardIter __result, _Tp*)
{
typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;
return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());
}
// 如果是trival construct,直接内存拷贝
template <class _InputIter, class _ForwardIter>
inline _ForwardIter
__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
_ForwardIter __result,
__true_type)
{
return copy(__first, __last, __result);
}
// 如果是non-trival construct,挨个复制
template <class _InputIter, class _ForwardIter>
_ForwardIter
__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
_ForwardIter __result,
__false_type)
{
_ForwardIter __cur = __result;
__STL_TRY {
for ( ; __first != __last; ++__first, ++__cur)
_Construct(&*__cur, *__first);
return __cur;
}
__STL_UNWIND(_Destroy(__result, __cur));
}
针对char* 和 wchar_t* 两种类型,用memmove(直接移动内存内容)来执行复制行为,以下是两种类型的特化版本:
inline char* uninitialized_copy(const char* __first, const char* __last,
char* __result) {
memmove(__result, __first, __last - __first);
return __result + (__last - __first);
}
inline wchar_t*
uninitialized_copy(const wchar_t* __first, const wchar_t* __last,
wchar_t* __result)
{
memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
return __result + (__last - __first);
}
二、uninitialized_fill:区间单值填充
template <class _ForwardIter, class _Tp>
inline void uninitialized_fill(_ForwardIter __first,
_ForwardIter __last,
const _Tp& __x)
{
__uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first));
}
可以看出,就是将__x的值复制到[__first,__last),复制的技法和uninitialized_copy类似。注意这里的__first和__last是目标迭代器。
三、uninitialized_fill_n
template <class _ForwardIter, class _Size, class _Tp>
inline _ForwardIter
uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x)
{
return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first));
}
和上一个函数很相近,只不过是把区间终点换成区间长度了。
总结:以上三个函数,其实就是结合转调实现泛化和特化的一个过程。
个人感觉:char* 类型的特化,有点像打补丁,应该归属 __true_type那个版本中去,然后再特化,不调用copy()而调用memmove(),这样更好理解一些。