STL源码剖析——Traits编程技术

http://blog.csdn.net/chenhanzhun/article/details/39230529

前言

    在STL编程中,容器和算法是独立设计的,即数据结构和算法是独立设计的,连接容器和算法的桥梁就是迭代器了,迭代器使其独立设计成为可能。Traits编程技术是STL中最重要的编程技术,Traits可以获取一个类型的相关信息。在学习《STL源码剖析》时,看到关于这方面的知识,在这期间查找了一些资料,下面是我对该技术的理解。

Traits编程技术

       Traits可以获取一个类型的相关信息,首先我们看下面的程序:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. template <class T, class type>  
  2. void function(T t, type u) {  
  3.     type temp;   
  4.     // ... The rest work of function…  
  5. }  
     在上面的程序中, 我们怎么样才能获得已声明变量 temp 的类型 type 呢?在模板中,模板参数推导机制可以解决这个问题,在下面程序中编译器直到变量 temp 的类型为 int

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. template <class T, class type>  
  2. void function(T iter, type u)   
  3. {  
  4.     type temp; // 通过模板参数推导获得temp变量的类型  
  5.     ....  
  6. }  
  7. template <class T>  
  8. void func(T iter)   
  9. {  
  10.     function(iter, *iter);   
  11. }  
  12.   
  13. int main()  
  14. {  
  15.     int i = 12;  
  16.     func(&i)  
  17. }  
          上面介绍的是获得局部变量的类型,这个可以通过模板参数推导机制完成;如果我们要获得函数返回值的类型时,该怎么处理呢?这个问题针对不同类型有不同的方法可以解决,类型型别:用户自定义类型(如结构体,类)和内置类型(如整型,原生指针等)。

    若我们要知道用户自定义类型的函数返回值类型,我们可以使用内嵌型别技术就可以知道返回值的类型;看下面程序:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. templates <class T>  
  2. struct Iterator   
  3. {  
  4. typedef T value_type;//内嵌型别声明  
  5. ...  
  6. };  
  7.   
  8. template <class Iterator>  
  9. typename Iterator::value_type //返回值类型  
  10. GetValue(Iterator iter)   
  11. {  
  12.     return *iter;  
  13. }  
  14.   
  15. int main()  
  16. {  
  17.     ...  
  18.     Iterator<int> ite(new int(9));  
  19.     std::cout<<GetValue(ite)<<std::endl;  
  20.     return 0;  
  21. }  
          用户自定义类型中我们可以通过内嵌型别获得返回值的类型,若不是用户自定义的类型,而是内置类型时,例如是原生指针,这时候该怎么处理呢?因为原生指针不能内嵌型别声明,所以内嵌型别在这里不适用。于是Traits技术就出现了。以下利用Traits技术也可以获取用户自定义类型的返回值类型。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. template <class Iterator>  
  2. struct iterator_traits {  
  3.   typedef typename Iterator::value_type    value_type;  
  4.   ...  
  5. };  
  6.   
  7. template <class Iterator>  
  8. typename iterator_traits<Iterator>::value_type //返回值类型  
  9. GetValue(Iterator iter)   
  10. {  
  11.     return *iter;  
  12. }  
     以上这种方法对原生指针不可行,所以 iterator_traits 针对原生指针的一个版本就应运而生。下面是针对 *Tp const *Tp 的版本,也称为 iterator_traits 版本的偏特化。iterator_traits的偏特化版本解决了原生指针的问题。现在不管迭代器是自定义类模板, 还是原生指针(Tp*, const Tp*),struct iterator_traits都能萃取出正确的value type类型。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. template <class Tp>  
  2. struct iterator_traits<Tp*> {  
  3.   typedef Tp       value_type;  
  4.   ...  
  5. };  
  6.   
  7. template <class Tp>  
  8. struct iterator_traits<const Tp*> {  
  9.   typedef Tp       value_type;  
  10.   ...  
  11. };  

          我们之所以要萃取 (Traits) 迭代器相关的类型,就是要把迭代器相关的类型用于声明局部变量、用作函数的返回值等一系列行为。对于原生指针和 point-to-const 类型的指针,采用模板偏特化技术对其进行特殊处理。要使用Traits功能,则必须自行以内嵌型别定义的方式定义出相应型别。我们上面讲解的只是迭代器其中一种类型value type,在迭代器中还有其他类型:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. template <class _Iterator>  
  2. struct iterator_traits {  
  3.   typedef typename _Iterator::iterator_category iterator_category; //迭代器类型  
  4.   typedef typename _Iterator::value_type        value_type;     //迭代器所指对象的类型  
  5.   typedef typename _Iterator::difference_type   difference_type;//迭代器之间距离  
  6.   typedef typename _Iterator::pointer           pointer;        //迭代器所指之物  
  7.   typedef typename _Iterator::reference         reference;      //迭代器引用之物  
  8. };  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值