STL—迭代器相关类型

迭代器相关类型(associated types)—迭代器指向元素的类型,及此类型衍生的出来的类型。如:

std::vector<int>::iterator it; 
//此迭代器相关类型为: int(value_type), int*(pointer), int&(reference), size_t(difference_type),

那么迭代器相关类型有什么用呢?我们将std::max_element(原型如下)稍微修改一下,将std::max_element的返回值修改为最大值,而不是指向最大值的迭代器。怎么做?

// std::max_element原型
template <class ForwardIterator>
  ForwardIterator max_element ( ForwardIterator first, ForwardIterator last )
{
  if (first==last) return last;
  ForwardIterator largest = first;
  while (++first!=last)
    if (*largest<*first)    // or: if (comp(*largest,*first)) for version (2)
      largest=first;
  return largest;
}

假设我们的输入为vector::iterator,现在我们只知道输入是指向int类型的迭代器,要返回一个int型的数据却不知道怎么表达。其实这个问题STL已经为我们解决好了。
traits技术
traits技术的中心思想—为每一个class type的迭代器定义它的相关类型(value_type、pointer、 reference、difference_type),并使用iterator_traits迭代器的相关类型。
现在我们实现一个简单的迭代器,并进行类型的提取:

template <typename elemType>
class MyIter {
    typedef elemType   value_type;
    typedef elemType*  pointer;
    typedef elemType&  reference;
    typedef size_t     difference_type;
    // ...
};
// 类型提取
template <typename ForwardIterator>
①typename ForwardIterator::value_type
max_element(ForwardIterator first, ForwardIterator last)
{
  if (first==last) return *last;
  ForwardIterator largest = first;
  while (++first!=last)
    if (*largest<*first)    // or: if (comp(*largest,*first)) for version (2)
      largest=first;
  return *largest;
}

此时类型提取的问题已经解决,但是到目前为止我们并没有用到iterator_traits,那么iterator_traits到底有什么用?刚才我们说到为每一个class type迭代器定义相关类型,非class type呢?如int, double*, …,别忘了我们一样可以向std::max_element传入数组指针。非*class type没有办法像class type一样在内部定义value_type,reference等相关类型(associated type。那么非*class type如何像class type一样使用typename ForwardIterator::value_type来提取相关类型呢?我们且看iterator_traits定义:

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;
};

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

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

正如看到的那样,iterator_traits有两个特化版本,有了这两个特化版本,不管是非class type的迭代器(如int或是const int)还是class type型迭代器 都可以通过iterator_traits来提取其相关类型。此时max_element就可以使用同一份实现。max_element就可以修改成这样:

// 类型提取
template <typename ForwardIterator>
typename iterator_traits<ForwardIterator>::value_type
max_element(ForwardIterator first, ForwardIterator last)
{
  if (first==last) return *last;
  ForwardIterator largest = first;
  while (++first!=last)
    if (*largest<*first)    // or: if (comp(*largest,*first)) for version (2)
      largest=first;
  return *largest;
}
// 类似实现std::distance

注①:ForwardIterator没有实例化之前,编译器并不知道ForwairdIterator::value_type代表的是什么,翻译器可以将之猜测为一个类的静态变量,亦或是一个静态方法。所以要请编译器知道它是一个类型,那么就需要在之前加上一个typename

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值