您的位置:首页 > 大数据 > 人工智能

STL源码-traits的使用

2013-09-12 13:00 323 查看
关于iterator traits和type traits的使用,我们什么时候会使用这两个类?我们怎么使用?

//问题:将[first1,last1)区间内的元素复制一遍。
//我们需要知道first1迭代器的类型。。
template<class _Iter>
_Iter copy(_Iter first1,_Iter last1)
{
//首先需要分配足够的空间,即迭代器所指元素的大小乘以个数
typedef typename iterator_traits<_Iter>::value_type _T;
_T* __result=new _T[last1-first1];
//然后我们需要进行复制
_T* __p=__result;
for(;first1!=last1;++first1,++__p){
//这里的复制,我们需要知道_T是否是具有快速的复制构造函数
typedef typename __type_traits<_T>::has_trivial_copy_constructor   _Copy_traits;
//如果_Copy_traits是__true_type那么就使用快速的copy,如果是__false_type那么就使用慢的copy,这里怎么判断两者相等
//是个问题。。。
//方法一:
_Copy_traits __ct;__true_type __tt;
if(typeid(__ct)==typeid(__tt)){__quick_copy(__p,__first);}
else __normal_copy(__p,__first);
//方法二:
//mfc中的策略
//方法三:利用函数的重载机制和模板推断机制
__copy(_Iter(__p),__first,_Copy_traits());
}
return _Iter(__result);
}
template<class _Iter>
void __copy(_Iter __dest,_Iter __source,__true_type)
{
__quick_copy(__dest,__source);
}
template<class _Iter>
void __copy(_Iter __dest,_Iter __source,__false_type)
{
__normal_copy(__dest,__source);
}


这就是traits使用的大体情况,这里stl中使用的统一技术就是函数重载与模板推断机制

举两个stl中的例子:他们遵循的模式都是:定义接口--利用模板推断和重载将任务分配或者说是路由-----特化特定的类型提高速度

//两个例子:
template <class _Tp>
inline void destroy(_Tp* __pointer) {
__pointer->~_Tp();
}

//补充__VALUE_TYPE
template <class _Iter>
inline typename iterator_traits<_Iter>::value_type*
__value_type(const _Iter&)
{
return static_cast<typename iterator_traits<_Iter>::value_type*>(0);//返回的是指针,这里的技术需要注意
}
template <class _Iter>
inline typename iterator_traits<_Iter>::value_type*
value_type(const _Iter& __i) { return __value_type(__i); }

#define __VALUE_TYPE(__i)  value_type(__i)

//销毁对象,下面使用的策略是、其实完全不必要,只是为了在stl中使用一致的策略
template <class _ForwardIterator>
inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) {
__destroy(__first, __last, __VALUE_TYPE(__first));//根据迭代器萃取类型信息
}
template <class _ForwardIterator, class _Tp>
inline void
__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*)//我们需要类型信息
{
typedef typename __type_traits<_Tp>::has_trivial_destructor
_Trivial_destructor;
__destroy_aux(__first, __last, _Trivial_destructor());
}
template <class _ForwardIterator>
void
__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type)
{
for ( ; __first != __last; ++__first)
destroy(&*__first);//传递给destroy的是指针,此处主要是迭代器与指针的不兼容性
}

template <class _ForwardIterator>
inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}
//特化
inline void _Destroy(char*, char*) {}
inline void _Destroy(int*, int*) {}
inline void _Destroy(long*, long*) {}
inline void _Destroy(float*, float*) {}
inline void _Destroy(double*, double*) {}

//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));
}

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());
}

template <class _InputIter, class _ForwardIter>
inline _ForwardIter __uninitialized_copy_aux(_InputIter __first, _InputIter __last,_ForwardIter __result,__true_type)
{
return copy(__first, __last, __result);
}
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的特化版本
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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: