《STL源码剖析》学习笔记2——神奇的__type_traits

标签:C,C++,STL,学习,笔记

 

  在STL中为了提供通用的操作而又不损失效率,我们用到了一种特殊的技巧,叫traits编程技巧。具体的来说,traits就是通过定义一些结构体或类,并利用模板类特化和偏特化的能力,给类型赋予一些特性,这些特性根据类型的不同而异。在程序设计中可以使用这些traits来判断一个类型的一些特性,引发C++的函数重载机制,实现同一种操作因类型不同而异的效果。traits的编程技巧极度弥补了C++语言的不足 。

 
举例:
 
现在定义一个__type_traits可以获得类型的如下属性:
1. 是否存在non-trivial default constructor
2. 是否存在non-trivial copy constructor
3. 是否存在non-trivial assignment operator
4. 是否存在non-trivial destructor
 
struct __true_type {
};
struct __false_type {
};
 
template
struct __type_traits { 

 
  typedef __false_type    has_trivial_default_constructor;
   typedef __false_type    has_trivial_copy_constructor;
   typedef __false_type    has_trivial_assignment_operator;
   typedef __false_type    has_trivial_destructor;
};
 
问题:为什么把对象的所有的属性都定义为__false_type?
这样是采用最保守的做法,先把所有的对象属性都设置为__false_type,然后在针对每个基本数据类型设计特化的__type_traits,就可以达到预期的目的,如可以定义__type_traits如下:
 
template <>
struct __type_traits {
   typedef __true_type    has_trivial_default_constructor;
   typedef __true_type    has_trivial_copy_constructor;
   typedef __true_type    has_trivial_assignment_operator;
   typedef __true_type    has_trivial_destructor;
};
 
template <>
struct __type_traits {
   typedef __true_type    has_trivial_default_constructor;
   typedef __true_type    has_trivial_copy_constructor;
   typedef __true_type    has_trivial_assignment_operator;
   typedef __true_type    has_trivial_destructor;
};
 
    ......
 
    ......
 
其他基本类型的traits也可以有相应的定义
 
__type_traits的偏特化版本
template
struct __type_traits<_Tp*> {
   typedef __true_type    has_trivial_default_constructor;
   typedef __true_type    has_trivial_copy_constructor;
   typedef __true_type    has_trivial_assignment_operator;
   typedef __true_type    has_trivial_destructor;
   typedef __true_type    is_POD_type;
};
 
我们可以自定义__type_traits的特化版本
比如对与自定义的Shape类型,我们可以这样定义__type_traits
struct __type_traits {
   typedef __false_type    has_trivial_default_constructor;
   typedef __true_type    has_trivial_copy_constructor;
   typedef __true_type    has_trivial_assignment_operator;
   typedef __true_type    has_trivial_destructor;
   typedef __true_type    is_POD_type;
};
 
如果编译器够厉害,我们甚至可以不用自己去定义特化的__type_traits,编译器就能够帮我们搞定:)
 
如何使用呢?
 
假设现在用个模板函数fun需要根据类型T是否有non-trivial constructor来进行不同的操作,可以这样来实现:
 
template
void fun()
{
     typedef typename __type_traits::has_trivial_constructor _Trivial_constructor;
    __fun(_Trivial_constructor()); // 根据得到的_Trivial_constructor来调用相应的函数
}
 
// 两个重载的函数
void __fun(__true_type )    
{ .....  }
 
void __fun(__false_type )
{ ...... }
 

你可能感兴趣的:(C/C++,学习笔记)