STL中迭代器(iterators)概念与traits编程技法

最近在学习jjhou的《STL源码剖析》,侯大师确实功力深厚,把SGI版本的STL解析的很透彻。让我等凡人能有机会窥见一些C++标准模板库的玄妙。看了第三章的内容,于是打算总结一番,方便后续继续学习。

迭代器模式

提供了一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式。

STL中的迭代器

STL的中心思想在于:将数据容器(containers)和算法(algorithms)分开,彼此独立设计,最后再以一贴胶着剂将它们撮合在一起。容器和算法的泛型化,可以用C++的class template 和 function template 来实现。而迭代器就是两者之间的胶着剂。

find( )方法中循环所满足的条件:

// 要么找到value,返回*first(指向value);要么没找到,最后返回last,终止while循环
while(first != last && *first != value)
    ++first;
return first;

iterator是一种行为类似指针的对象,指针最重要的便是内容提领(dereference)和成员访问(member access)。因此iterator最重要的是对operator*和operator->进行重载的工作。

迭代器相应型别(associated types)

associated types总共有五种类型: value_type,difference_type,pointer,reference,iterator_cotegory。

其中value_type可以利用function template的argument deducation,但是它只能推导参数的型别,无法推导函数的返回值的型别。

Partial Specialization(偏特化)的意义

在泛化设计中提供了一个特化版本(将泛化版本中的某些template参数赋予明确的指定)。

利用模板的参数推断:

template<typename I, typename T>
void func_impl(I iter, T, t)
{
    T tmp; //这里解决了问题。T就是迭代器所指之物的型别,本例为int
    
    // ...这里做原本func()应该做的全部工作
};

template <typename I>
inline
void func(I iter)
{
  func_impl(iter, *iter); // func的工作全部移往func_impl 
};

int main()
{
    int i;
    func(&i);
}

万一value_type必须用于函数传回值,模板参数推导机制只能推断参数,而无法推断函数的回返值型别。我们需要其他的方法:声明内嵌。

template <typename T>
struct MyIter
{
    typedef T value_type; //内嵌型别声明(nested type)
    T* ptr;
    MyIter(T* p = 0):ptr(p){}
    T& operator*() const{return *ptr;}
    // ...
};

template <typename I>
typename I::value_type //这一行是func的回返值型别
func(I ite)
{
    return *ite;
}
// ...

MyIter<int> ite(new int (8));
cout<< func(ite); //输出 8

引入萃取:

template <typename T>
struct MyIter
{
    typedef T value_type; //内嵌型别声明(nested type)
    T* ptr;
    MyIter(T* p = 0):ptr(p){}
    T& operator*() const{return *ptr;}
    // ...
};

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

template <typename I>
typename iterator_traits<I>::value_type //这一行是func的回返值型别
func(I ite)
{
    return *ite;
}
// ...


MyIter<int> ite(new int (8));
cout<< func(ite); //输出 8


template <typename T>
struct iterator_traits<T*>
{
    typedef T value_type; //偏特化版,迭代器是个原生指针
};

引入萃取之后,不论面对的是迭代器MyIter,或是原生指针int*或是const int*,都可以通过traits取出正确的value_type。

大功告成

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值