zoukankan      html  css  js  c++  java
  • STL-traits编程技法

       不论是泛型思维或STL的实际运用,迭代器(iterators)都扮演者重要的角色。迭代器的中心思想在于:将数据容器(container)和算法分开,彼此独立设计,最后再以迭代器这种工具将两者粘合起来。

        

    一.模板特化与偏特化

        假设下面有一个class template如下:

    template<typename T>
    class C{...};
         

    《泛型思维》书中对partial specialization的定义是:"针对任何template参数更进一步的条件限制所设计出来的一个特化版本“。

     由此,上式的偏特化版本:

    template<typename T>
     class C<T*>{...};//这个版本仅适用于"T为原生指针"的情况
           //"T为原生指针"是对"T可为任何型别"的更进一步约束

    二.迭代器的相应型别

      最常用到的迭代器相应型别有五种:value type,difference type,pointer,reference,iterator category."特性萃取机"traits就是将迭代器这种特性榨取出来.

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

    value_type:指迭代器所指对象的型别,任何一个打算与STL算法有完美搭配的class,都应该定义自己的value_type内嵌型别。

    difference_type:用来表示两个迭代器之间的距离。

    reference_type:从迭代器所指之物是否允许改变,迭代器分为两种:不允许改变"所指对象之内容"者,称为constant iterators.允许改变"所指对象之内容"者,称为mutable iterators.

    pointer type:代表p所指之物的地址

    iterator_category:根据移动特性与施行操作,迭代器分为五类:

       Input Iterator:这种迭代器所指的对象,不允许外界改变,只读(read only)

       Output Iterator:唯写(write only)

       Forward Iterator:允许"写入型"算法,在此种迭代器形成的区间上进行读写操作。

       Bidirectional Iterator:可双向移动

       Random Access Iterator:前四种迭代器都指提供一部分指针算术能力,而此种迭代器涵盖所有指针算术能力,包括p+n,p-n,p[n],p1-p2.

      

     

    三.iterator源代码

       

    template<class I>
         struct iterator_traits{
              typedef typename I::iterator_category iterator_category;
              typedef typename I::value_type value_type;
              typedef typename I::reference reference;
              typedef typename I::pointer pointer;
              typedef typename I::difference_type difference_type;
         };
     
     template<class I,class T>
     typename iterator_traits<I>::difference_type 
                  count(I first,I last,const T&value){
               typename iterator_traits<I>::difference_type result=0;
               for(;first!=last;first++){
                   if(*first==value) ++n;
               }
               return n;
         }
         
         
         //五种迭代器类型
         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{};
         
         //为避免写代码时挂一漏万,自行开发的迭代器最好继承自下面的这个std::iterator
         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;
         };
         
         template<class Iterator>
         struct iterator_traits{
             typedef typename Iterator::iterator_category iteator_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;
         };
         
         //针对原生指针(native pointer)而设计的traits偏特化版
         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;
         };
          
    ...

      

  • 相关阅读:
    如何将网格式报表打印成其它样式
    拥有与实力不相称的脾气是种灾难——北漂18年(23)
    8.8.1 Optimizing Queries with EXPLAIN
    mysql 没有rowid 怎么实现根据rowid回表呢?
    secondary index
    8.5.5 Bulk Data Loading for InnoDB Tables 批量数据加载
    mysql 中key 指的是索引
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo 日志
    8.5.3 Optimizing InnoDB Read-Only Transactions 优化InnoDB 只读事务
    8.5.1 Optimizing Storage Layout for InnoDB Tables InnoDB表的存储布局优化
  • 原文地址:https://www.cnblogs.com/sixue/p/4317684.html
Copyright © 2011-2022 走看看