在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 <class _Tp>
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<int>如下:

template <>
struct __type_traits<int> {
   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<char> {
   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 <class _Tp>
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<Shape>
struct __type_traits<Shape> {
   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<class T>
void fun()
{
     typedef typename __type_traits<T>::has_trivial_constructor _Trivial_constructor;
    __fun(_Trivial_constructor()); // 根据得到的_Trivial_constructor来调用相应的函数
}

// 两个重载的函数
void _fun(_true_type)
{
cout<<"fun(_true_type)called"<<endl;
}
void _fun(_false_type)
{
cout<<"fun(_false_type) called"<<endl;
}

//测试代码

int main()
{
fun<char>();
fun<int>();
fun<char *>();
fun<double>();
}

最新文章

  1. Unicode转义(\uXXXX)的编码和解码
  2. python(一)
  3. jquery+bootstrap实现tab切换, 每次切换时都请求数据, 点击提交分别向不同的地址提交数据
  4. 一些gcd计数问题
  5. 通过反射获得 spring 的 RequestMapping value值
  6. DOM (Document Object Model)文档对象模型
  7. 在无修改权限的情况下修改文件hosts中的内容
  8. [论文笔记] Methodologies for Data Quality Assessment and Improvement (ACM Comput.Surv, 2009) (1)
  9. ava SE ---逻辑运算符
  10. POJ2892Tunnel Warfare (线段树)
  11. ios学习基础篇一
  12. 离线安装mysql数据库
  13. &quot;敏捷革命&quot;读书笔记
  14. servlet3.1
  15. 《linux内核设计与分析》内核模块编程
  16. zookeeper报错: org.I0Itec.zkclient.exception.ZkMarshallingError: java.io.EOFException
  17. 阿里八八Alpha阶段Scrum(2/12)
  18. aiohttp基本及进阶使用
  19. codeforces 578c//Weakness and Poorness// Codeforces Round #320 (Div. 1)
  20. gocommand:一个跨平台的golang命令行执行package

热门文章

  1. C# DataGridView 导出 Excel(根据Excel版本显示选择不同后缀格式xls或xlsx)
  2. Ubuntu 中使用 谷歌日历
  3. MFC添加自定义消息
  4. AC自动机:BZOJ 2434 阿狸的打字机
  5. 【扩展欧几里得】BAPC2014 I Interesting Integers (Codeforces GYM 100526)
  6. A - Til the Cows Come Home
  7. JavaScript交换两个变量值的七种解决方案
  8. QML 语言基础
  9. Nginx优化具体,应对高并发
  10. cocos2d-x 3.0 利用python脚本在文件夹Classes内创建class