Iterator_trait总结

1. 从STL源码中了解Iterator_trait

以rotate算法为例

template<typename _ForwardIterator>
inline void rotate(_ForwardIterator _first,
                   _ForwardIterator _middle,
                   _ForwardIterator _last,)
{
    //...
    std::_rotate(_first, _middle, _last,
                 std::__iterator_category(_first));
}
template<typename _Iter>
inline typename iterator_trait<_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)
{
    //....
    typdef typename iterator_trait<_RandomAccessIterator>::different_type _Distance;
    typdef typename iterator_trait<_RandomAccessIterator>::value_type _VlaueType;
    _Distance_n = _last - _first;
    _Distance_k = _middle - _first;
    // ....
    for(;;) {
        //....
    }
}

从上述代码中可以看出,rotate()需要知道iterators的三个associated types,即:

  • iterator_trait::iterator_category()
  • iterator_trait<_RandomAccessIterator>::different_type __Distance
  • iterator_trait<_RandomAccessIterator>::value_type _VlaueType

Iterators必须有能力回答algorithms的提问,这样的提问在C++标准库开发过程中设计出了5种,另外2种从未在C++标准库中被使用过:reference和pointer。

注:typedef typename 的作用

typdef typename iterator_trait<_RandomAccessIterator>::different_type _Distance;
typedef创建了存在类型的别名,而typename告诉编译器iterator_trait<_RandomAccessIterator>::different_type是一个类型而不是一个成员。

2. Iterator的5种associated types

// G4.9
template<typename _Tp>
struct _List_iterator
{
    typedef std::bidirectional_iterator_tag iterator_category;
    typedef _Tp value_type;
    typedef _Tp* pointer;
    typedef _Tp& reference;
    typedef ptrdiff_t difference_type;
}

如上所示,如果 I(iterator)是 class,class iterator 都有能力定义自己的associated type,因此以直接回答算法提问。

template<typename I>
inline void algorithm(I first, I last)
{
    //...
    I::iterator_category;
    I::pointer;
    I::reference;
    I::value_type;
    I::difference_type;
    //...
}

如果 I(iterator) 并不是 class,例如它是一个 native pointer(被视为一种退化的iterator),它无法定义自己的associated type,因此并不能回答算法的提问。traits 必须具有分别它获取的 iterator 是 class iterator T 还是native pointer to T。利用partial specialization可达到目的。

3. Itreator_trait源码实现

template <class T>
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;
};

template <class T>
struct iterator_traits<T*> {
    typedef typename random_access_iterator_tag iterator_category;
    typedef typename T value_type;
    typedef typename ptrdiff_t difference_type;
    typedef typename T* pointer;
    typedef typename T& reference;
};

template <class T>
struct iterator_traits<const T*> {
    typedef typename random_access_iterator_tag iterator_category;
    typedef typename T value_type;
    typedef typename ptrdiff_t difference_type;
    typedef typename T* pointer;
    typedef typename T& reference;
};

注:const T*类型的Iterator中value_type不是const T,value_type的主要目的是用来声明变量,声明一个无法被复制的变量没有什么用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值