STL中traits编程技法

来源:互联网 发布:wow7.3mac系统 编辑:程序博客网 时间:2024/05/16 12:10

在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_NAMESPACEStemplate <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_SPECIALIZATIONtemplate <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
原创粉丝点击