首页 > 其他 > 详细

“类型萃取器”__type_traits

时间:2014-04-27 11:19:21      阅读:599      评论:0      收藏:0      [点我收藏+]
iterator_traits负责萃取迭代器的五种特性,__type_traits则负责萃取类型特性,即某种类型是否具有琐碎无意义(trivial)的构造函数或复制控制,即POD类型。

__type_traits定义于<type_traits.h>中:
struct __true_type {
};
 
struct __false_type {
};

template <class type>
struct __type_traits { 
   ...
   typedef __false_type    has_trivial_default_constructor;
   typedef __false_type    has_trivial_copy_constructor;
   typedef __false_type    has_trivial_assignment_operator;
   typedef __false_type    has_trivial_destructor;
   typedef __false_type    is_POD_type;
};


默认情况下,认为所有类型都为non-trivial,下面再给出内置类型的特化版本,如:
__STL_TEMPLATE_NULL struct __type_traits<char> {
   typedef __true_type    has_trivial_default_constructor;
   typedef __true_type    has_trivial_copy_constructor;
   typedef __true_type    has_trivial_assignment_operator;
   typedef __true_type    has_trivial_destructor;
   typedef __true_type    is_POD_type;
};


这里,就认为char类型具有trivial的构造和复制控制。注意,这些嵌套类型要么返回__true_type类型,要么返回__false_type类型,根据类型不同而编译时期确定该调用哪个版本的函数。

下面来看看__type_traits的应用。
template <class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,
                                            const T& x) {
  return __uninitialized_fill_n(first, n, x, value_type(first));
}

此全局函数从迭代器first开始,在未初始化的空间内填充n个元素,值为x。

首先来分析函数value_type:
template <class Iterator>
inline typename iterator_traits<Iterator>::value_type*
value_type(const Iterator&) { // 决定迭代器value_type
  return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
}

它首先利用iterator_traits获得迭代器所指类型的value_type,然后返回这个value_type的指针。

template <class ForwardIterator, class Size, class T, class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n,
                                              const T& x, T1*) {
  typedef typename __type_traits<T1>::is_POD_type is_POD;
  return __uninitialized_fill_n_aux(first, n, x, is_POD());
                                     
}

函数__uninitialized_fill_n接受到这个指针后,利用__type_traits机制来判断T1是否是POD类型。

如果是POD类型,is_POD()应该生成一个临时对象——__true_type,然后调用对应的重载函数:
template <class ForwardIterator, class Size, class T>
inline ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
                           const T& x, __true_type) {
  return fill_n(first, n, x);
}

STL算法fill_n直接对first指向的内存逐一赋值,因为是POD类型。

如果不是POD类型,is_POD()应该生成一个临时对象——__false_type,然后调用对应的重载函数:
template <class ForwardIterator, class Size, class T>
ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
                           const T& x, __false_type) {
  ForwardIterator cur = first;
  __STL_TRY {
    for ( ; n > 0; --n, ++cur)
      construct(&*cur, x);
    return cur;
  }
  __STL_UNWIND(destroy(first, cur));
}

调用全局函数construct(),对每个位置使用构造函数来进行初始化。

从上面的例子可以看出,__type_traits的目的就是要提取出某种类型的特性:has_trivial_default_constructor?
has_trivial_copy_constructor?
...
然后再根据这些特性选择效率最高的函数进行调用,是性能达到最大优化。

参考:
《STL源码剖析》 P103.

“类型萃取器”__type_traits,布布扣,bubuko.com

“类型萃取器”__type_traits

原文:http://blog.csdn.net/nestler/article/details/24575857

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!