现在的位置: 首页 > 综合 > 正文

STL的榨汁机——type traits

2018年02月23日 ⁄ 综合 ⁄ 共 2384字 ⁄ 字号 评论关闭
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( in,
                            iterator_traits <InputIterator >::iterator_category());        //创建临时对象,此对象是无用的,只是为了进行参数推导。
}

抱歉!评论已关闭.