《STL源码剖析》traits技法分析

来源:互联网 发布:洛瑟玛·塞隆 知乎 编辑:程序博客网 时间:2024/05/16 23:49

在完成一个迭代器的时候,我们可能会暴露太多的细节在外面,为了将这些细节给隐藏,我们需要封装,这也是为什么每一种STL容器都提供了一种专属的迭代器。
为了解决以“迭代器所指对象的型别”为型别
解决办法是:利用template的参数推导(argument deducation)

template<class I,class T>void func_impl(T iter,T t){    T temp;//这里解决了问题,T就是所指的对象的型别};template<class I>void func(I iter){ func_impl(iter,*iter);//传入的一个是迭代器,一个是迭代器所指的对象的类型}

这里编译器会自动进行template类型推导,于是可以推导出型别T,顺利解决问题。
(迭代器相应型别不止是迭代器所指对象的型别一种,最常用的有5种:value_type,difference_type,reference_type,pointer_type,iterator_category)


为了解决以迭代器所指对象型别为返回值的问题
在这里我们使用声明内嵌型类型来解决问题:

template<class T>struct MyIter{typedef T value_type;//声明内嵌型型别(nested type)T*ptr;MyIter(T*p=0):ptr(p){}T&operator*(){return *ptr}};template<class I>typename I::type_valuefunc(I ite){return *ite;}int main(){MyIter<int> ite(new int(8));cout<<func(ite);//输出结果为8}

但是这种方法有一个隐藏的缺点:无法为原生指针类型制作迭代器,因为内建类型无法定义内部的value_type,所以我们还需要针对特定情况做特定的处理,这时候我们需要特偏化处理(template partial specialization)


特偏化(template partial specialization)
(1) 类模板的偏特化
例如c++标准库中的类vector的定义
template

template<class T>struct iterator_traits{typedef typename T::value_type value_type;//这里多加了一层封装,好处是traits可以拥有特化的版本(这里我还是不清楚,为什么说加了封装才能有特化的版本?)};//特化的版本1,为了解决原生指针,比如:int*template<class T>struct iterator_traits<T*>{    typename T value_type;//如果是个Int*,可以萃取出int类型};//特化版本2,为了解决原生的const指针,比如:const int*template<class T>struct iterator_traits<const T*>{    typename T value_type;//如果是个const int*,可以从中萃取出int类型}

这里写图片描述
最后的效果就像图中这样。

1 0