STL源码剖析学习笔记(三)

STL源码剖析学习笔记(三)

iterator和traits编程技法(下)

前面说到,利用模板的参数推导机制可以推导参数,但是如果我们需要该类型的返回值作为参数,则无法通过这个方法获取,这个时候,就需要内建类型
什么是内建类型呢?我们还用程序来举例子:

template <typename T>
class myIterator
{
 ...
};

这样一个模板类里,我们需要获取T的类型,可以利用typedef

template <typename T>
class myIterator
{
      typedef  T value_type; 
...
};

这样,当我们需要T的类型作为函数的返回值的时候,可以这么写

template<typename T>
typename T::value_type func(T x){
};

注意这里的typename T::value_type 是函数的返回值类型,这里用typename关键字,也是因为如果不加的话,编译器不知道T::value_type是一个类型还是一个成员变量。

这样,我们就可以利用这个特性来写iterator的萃取器trait了。
看好下面这个代码

template<class I>
struct iterator_traits{
    typedef typename I::value_type value_type
};

刚才的函数就可以写成

template<class T>
typename iterator_traits<T>::value_type func(T x){
};

即如果你这个模板T一旦定义了内嵌类型value_type,你就可以使用iterator_traits将其value_type萃取出来,这么多一层包裹的意义是什么呢?前面说过,原生指针类型必须是iterator,比方说int*,它并没有定义value_type,就无法做到模板的统一了,那么这里迭代器的traits就利用了模板的偏特化这样一个特性,定义了原生指针的value_type
什么是偏特化?简单点说:
template<class T,class I>是基础版本,那么
template<class T,int>就是偏特化版本,而
template<class T,class I*>也是偏特化版本,
template<char, int>就是全特化版本了。
编译器对模板对号入座的时候,先考虑全特化,再考虑偏特化,最后考虑基础版本。说到这里,我们就可以让原生指针的萃取器trait变成一个偏特化的版本:

template <class T>
struct iterator_traits<T*>{
typedef T value_type;
};
template <class T>
struct iterator_traits<const T*>{
typedef T value_type;
};

这样就解决了原生指针的问题。

迭代器通常需要定义以下几个type:

  1. value_type;
  2. difference_type;
  3. pointer;
  4. reference;
  5. iterator_category;

第一个不用说了;第二个定义了表示两个迭代器之间“距离”这样一个东西的类型;第三个和第四个可以用以下两个式子来解释Item* operator->() const {return ptr;} Item& operator*() const {return *ptr;} 前者返回值就是pointer,后者就是reference;第五个是指迭代器的类型,有以下几种:
1. input iterator
2. output iterator
3. forward iterator
4. bidirectional iterator
5. random access iterator

原生指针是第五个种类哦。
这里的五个级别,以最强的那个为准,当你针对迭代器写函数的时候,如果它是random access iterator,那么它一定也是1、3、4或者2、3、4,那么针对它写的偏特化版本的函数模板,就不一定适用于1、2、3、4,因为它级别最高。

下一篇将讲述一些基本的容器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值