C++STL 体系结构与内核分析(侯捷)——课程笔记(五)

本部分包括traits基础以及iterator traits的介绍

一、iterator需要遵循的原则

STL中的iterator是关联algorithms和containers的纽带,algorithms想要通过iterator处理元素,有几个iterator必须要回答给algorithms的问题,比如说iterator指向元素的类型,iterator的类别等等,下面是一个例子:

template<typename _ForwardIterator>
    inline void
    rotate(_ForwardIterator __first,
           _ForwardIterator __middle
           _ForwardIterator __last)
    {
    ......
    std::__rotate(__first, __middle, __last,
                  std::__iterator_catagory(__first));
    }


template<typename _Iter>
    inline typename iterator_traits<_Iter>::iterator_category
    __iterator_category(const _Iter&)
    { return typename iterator_traits<_Iter>::iterator_category(); }


template<typename _RandomAccessIterator>
    void
    __rotate(_RandomAccessIterator __first,
             _RandomAccessIterator __middle,
             _RandomAccessIterator __last,
             random_access_iterator_tag)
{
......
    typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance;
    typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType;
    _Distance __n = __last - __first;
    _Distance __k = __middle - __first;
......
}

这个例子中,算法中的函数rotate就必须知道迭代器的差的类型,所指元素的类型,以及迭代器本身的类别这三个信息。

所以,所有的iterator定义5个相同的associated types,就可以以一致的方式“告诉”algorithms它需要的这些信息,有5个typedef是所有的iterator都需要定义的,如下图所示:

那么既然有了associated types,我们为什么还需要traits呢?以iterator的associated types为例,假如我们传给algorithms的是native pointer,那么它怎么回答algorithms提出的五个问题呢?这就要引出traits的概念,iterator traits可以统一地处理class iterator和non-class iterator。

二、traits

traits可以理解为一种萃取机制,可以提取出某一些东西的一些相同的特性。比如iterator traits可以统一地处理class iterator和non-class iterator,以统一的方式提取出它们的五个associated types,这是通过模板的偏特化来实现的,如下所示:

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


//partial specialization for regular pointers
template<class T>
struct iterator_traits<T*>{
    typedef random_access_iterator_tag    iterater_category;
    typedef T                             value_type;
    typedef ptrdiff_t                     difference_type;
    typedef T*                            pointer;
    typedef T&                            reference;
};

//partial specialization for regular const pointers
template<class T>
struct iterator_traits<const T*>{
    typedef random_access_iterator_tag    iterater_category;
    typedef T                             value_type;
    typedef ptrdiff_t                     difference_type;
    typedef const T*                      pointer;
    typedef const T&                      reference;
};

注意针对const T*的偏特化版本中的value_type是T而不是const T,这是因为value_type的主要目的是为了声明变量,而声明一个无法被赋值的变量没什么用。

三、各式各样的traits

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值