STL中traits编程技法

在STL中迭代器是容器与泛型算法之间的粘合剂。要想使泛型算法独立于容器,泛型算法必须以迭代器为对外接口,同时要想容器能独立于泛型算法,容器必须有专属的迭代器。

1.oterator_traits

在算法中运用迭代器时,很有可能会用到迭代器的相应型别。假设算法要以“迭代器所指之物的型别(value_type)”定义对象,如何是好?解决办法是利用函数模板的参数推导机制。例如:


但是如果我们要使用value_type作为函数返回值类型,上述方法就行不通了。怎么办?申明内嵌型别是个不错的主意,像这样:


这个方法看起来不错,但是有个隐晦的陷阱:并不是所有的迭代器都是class type,原生指针就不是class,就无法为它定义内嵌型别,但是所有的泛型算法必须能接受原生指针。类模板的偏特化可以解决这个问题:




这就是整个iterator_traits由来。对于任何迭代器,原生指针,const原生指针,只要使用iterator_traits<>都可以萃取出迭代器相应的型别。如下图所示:


整个iterator_traits源代码如下:

struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};

#ifdef __STL_USE_NAMESPACES
template <class Category, class T, class Distance = ptrdiff_t,
          class Pointer = T*, class Reference = T&>
struct iterator {
  typedef Category  iterator_category;
  typedef T         value_type;
  typedef Distance  difference_type;
  typedef Pointer   pointer;
  typedef Reference reference;
};
#endif /* __STL_USE_NAMESPACES */

#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION

template <class Iterator>
struct iterator_traits {
  typedef typename Iterator::iterator_category iterator_category;
  typedef typename Iterator::value_type        value_type;
  typedef typename Iterator::difference_type   difference_type;
  typedef typename Iterator::pointer           pointer;
  typedef typename Iterator::reference         reference;
};

template <class T>
struct iterator_traits<T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef T*                         pointer;
  typedef T&                         reference;
};

template <class T>
struct iterator_traits<const T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef const T*                   pointer;
  typedef const T&                   reference;



2.__type_traits

iterator_trats负责萃取迭代器特性,__type_traits则负责萃取某一型别的特性,所谓型别特性是指:这个型别是否具有non-trivial defalt ctor , non-trivial copy ctor , non-trivial assignment operator , non-trivial dtor ?如果答案是否定的,我们在对这个型别进行构造,析构,拷贝,赋值等操作时,就可以采取更有效率的措施。因此我们定义了__type_traits.源码如下:

template <class type>
struct __type_traits { 
   typedef __true_type     this_dummy_member_must_be_first;
   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;
};

这是采取了最保守的措施,所有的内嵌型别都被 定义为_false_type,针对每个标量型别,STL都设计了特化版本。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值