现在的位置: 首页 > 综合 > 正文

STL源码-traits的使用

2014年01月20日 ⁄ 综合 ⁄ 共 3778字 ⁄ 字号 评论关闭

 关于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);
}

抱歉!评论已关闭.