[转载]__type_traits
在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>();
}
[转载]__type_traits的更多相关文章
- [转载]浅析STL allocator
本文转载自水目沾博客:http://www.cnblogs.com/zhuwbox/p/3699977.html 向大师致敬 一般而言,我们习惯的 C++ 内存配置操作和释放操作是这样的: 1 c ...
- [转载]《STL源码剖析》阅读笔记之 迭代器及traits编程技法
本文从三方面总结迭代器 迭代器的思想 迭代器相应型别及traits思想 __type_traits思想 一 迭代器思想 迭代器的主要思想源于迭代器模式,其定义如下:提供一种方法,使之能够依 ...
- 转载:C++ typename的起源与用法
转载:http://feihu.me/blog/2014/the-origin-and-usage-of-typename/#typename 侯捷在Effective C++的中文版译序中提到: C ...
- Crystal Clear Applied: The Seven Properties of Running an Agile Project (转载)
作者Alistair Cockburn, Crystal Clear的7个成功要素,写得挺好. 敏捷方法的关注点,大家可以参考,太激动所以转载了. 原文:http://www.informit.com ...
- RTP与RTCP协议介绍(转载)
RTSP发起/终结流媒体.RTP传输流媒体数据 .RTCP对RTP进行控制,同步.RTP中没有连接的概念,本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完 ...
- 《Walking the callstack(转载)》
本文转载自:https://www.codeproject.com/articles/11132/walking-the-callstack Download demo project with so ...
- [转载]MVVM模式原理分析及实践
没有找到很好的MVVM模式介绍文章,简单找了一篇,分享一下.MVVM实现了UI\UE设计师(Expression Blend 4设计界面)和软件工程师的合理分工,在SilverLight.WPF.Wi ...
- [转载]:STM32为什么必须先配置时钟再配置GPIO
转载来源 :http://blog.csdn.net/fushiqianxun/article/details/7926442 [原创]:我来添两句,就是很多同学(包括我)之前搞低端单片机,到了stm ...
- [转载]从MyEclipse到IntelliJ IDEA-让你摆脱鼠标,全键盘操作
从MyEclipse转战到IntelliJ IDEA的经历 注转载址:http://blog.csdn.net/luoweifu/article/details/13985835 我一个朋友写了一篇“ ...
随机推荐
- ASP.NET页面不被缓存
设置ASP.NET页面不被缓存分类:ASP.NET (3531) (1) /// <summary> /// 设置页面不被缓存 /// </summa ...
- Pick-up sticks(判断两条线段是否相交)
Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8351 Accepted: 3068 Description Stan has ...
- MongoDB主从配置
master的配置 # cat mongod.conf dbpath = /app/sinova/mongodata/db #指定数据库目录 logpath = /app/sin ...
- 在Win7下用XManager远程控制ubuntu
在Win7下用XManager远程控制ubuntu 远程主机通过xdmcp协议连接到ubuntu的图形终端,以图形终端方式登录. 远程主机是win7.ubuntu装在VMware虚拟机上,ubun ...
- 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)
题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...
- HDU-1207 汉诺塔II
汉诺塔 四根所需要的步数的规律: 规律:a[1]=1;a[2]=a[1]+2;a[3]=a[2]+2;(2个加2^1)a[4]=a[3]+4;a[5]=a[4]+4;a[6]=a[5]+4;(3个加 ...
- 汇编学习笔记(7)call和ret指令
ret和retf CPU执行ret指令时进行以下两步操作: (IP)=((ss)*16+(sp)) (sp)=(sp)+2 这相当于pop IP CPU执行retf指令时进行以下四步操作: (IP)= ...
- cf602A Two Bases
A. Two Bases time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- hdu4666 最远曼哈顿距离
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4666 #include <cstdio> #include <cstring> ...
- 如何高性能的给UIImageView加个圆角
文/natewang(简书作者)原文链接:http://www.jianshu.com/p/268f3839d2e6著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 其实你只需要的是圆角 ...