STL的榨汁机——type traits

STL中关于类型提取器的详细介绍,我再此就不赘述了,只是记下其中关键部分,供我以后学习之用。

nested type,这种方法能获得一个类的associated type,如下代码中,想要获得myIter类的T类型,可以在此类中 nested一个typedef,将T保存下来,其他类中,就可以使用typename I::value_type来获得I类中nested进去的type(typename的作用就是告诉编译器I是一个类,不然无法通过编译)。
template  < class  T  >
struct   myIter
{
         typedef   T   value_type  ;
         T  * ptr;
       myIter(  T  *  p  = 0):ptr(  p ){}
         T & operator*()
       {
                return  *ptr;
       }
};

template  < class  I  >
typename   I  :: value_type
func(  I   ite )
{
       func_aux(  ite , *  ite );
         return  *  ite ;
}


当myIter如果是一个特别版本,比如一个原生指针(也可以看作一个迭代器),我们就无法拿到他的nested type,因为他是基本类型,根本就没有template,所以没有定义nested type。这样的话就要使用template partial specialization(偏特化)。
template  < class  T  >
class   C  {};     //泛化版本接受T为任何类型

template  < class  T  >
class   C  < T  *> {};        //这个特化版本仅接受T是一个原生指针的情况

下面是iterator_traits的代码,只简单取了一部分
template  < class  I  >
struct   iterator_traits  {
         typedef   typename   I ::  value_type   vaule_type  ;        //如果I有定义自己的value_type,就会被提取出来。
};
template  < class  I  >
struct   iterator_traits  <T*>{
         typedef  I vaule_type;        //特化版本,适用于原生指针
};
template  < class  I  >
struct   iterator_traits  < const  T*>{
         typedef  T vaule_type;        //特化版本,适用于const指针,并且返回的是一个非const对象。
};

STL中的iterator一共有五个属性:
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 ;
};

其他几个都比较简单,只有iterator_categoty比较复杂,我们需要使用它来进行参数推导,以便提高效率,我们可以看到下面的声明,因为要进行编译时期的参数推导,我们需要为这些类型定义成类。而不能只是一个typedef。如下的继承关系,越往下iterator的功能越强大,比如random_access_iterator_tag就可以随机访问,拥有此能力的迭代器,我们必须使用他的高级功能以提高效率。
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  {};

如果我要实现一个iterator,如下:
template  < class  T  >
struct   myIter
{
         typedef  bidirectional_iterator_tag  iterator_category  ;
};

调用时只需:
template  < class  InputIterator  class  Distance  >
inline   void  advance( InputIterator  & i  Distance  n  )
{
       __advance(  i n ,
                             iterator_traits  < InputIterator  >::iterator_category());         //创建临时对象,此对象是无用的,只是为了进行参数推导。
}

你可能感兴趣的:(C++)