STL — SGT STL的私房菜: __type_traits

SGT STL的私房菜: __type_traits




traits的编程技法非常的6,我们在前面的迭代器设计思维的时候已经领教过了,它适当的弥补了C++语言本身的不足. STL只对迭代器加

以规范,制定 iterator_traits. SGI把这种技法进一步扩大到迭代器以外的世界上,于是有了所谓的__type_traits. 双底线前缀词意

这是SGI STL内部所用的东 西 ,不在STL标准规范之内.


iterator_traits负责萃取迭代器的特性,__type_traits则负责萃取型别的特性. 此处我们所关注的型别特性是指:这个型别是否具备

non-trivial  defalt ctor(在我这里理解->非常规默认构造函数)? 是否具备non-trivial copy ctor()?是否具备 non-trivial 

assignment operator? 是否具备 non-trivial dtor?如果答案是否定的,我们在对这个型别进行构造,析构,拷贝,赋值等操作的时候,

就可以采用最有效率的措施,而采用内存直 接处理操作如 malloc(),memcpy()等等,获得最高效率. 这对于大规模而操作频繁的容器,

有这显著的效率提升.

定义于SGI<type_traits.h>中的__type_traits,提供了一种机制,允许针对不同的型别属性,在编译时期完成函数派送决定。 这对于撰

写template很 帮助,例如,当我们准备对一个"元素型别未知"的数组执行copy操作时,如果我们能事先知道其元素型别是否有一个

trivial copy constructor,便 能够 帮助我们决定是否可使用快速的memcpy()或memove().

根据我们的iterator_traits得来的经验,我们希望,程序之中可以这样运用__type_traits<T>,T代表任意型别:

__type_traits<T>::has_trivial_default_constructor
__type_traits<T>::has_trivial_copy_constructor
__type_traits<T>::has_trivial_assignment_operator
__type_traits<T>::has_trivial_destructor
__type_traits<T>::is_POD_type //POD: Plain Old Data

所以现在已经很容易了,我们只需要判断上面这几项是真是假就结束了.   但是上面传输的结果不能单纯是一个bool值,应该是

个有着真/假性质的对 象,因为我们希望利用其响应结果来进行参数推导,而编译器只有面对class object形式的参数,才会做参数

推导. 为此,上述式子应该传会这样的东 西:

struct __true_type {
};

struct __false_type {
};

这两个空白的classes没有任何成员,不会带来额外的负担,却又能够标示真假,满足我们所需:

为了达到上述的五个式子,__type_traits内定义一些typedefs,其值不是__true_type就是__false_type。 下面看看SGI STL源代码:

template <class type>
struct __type_traits {
	typedef __true_type     this_dummy_member_must_be_first;
	/* Do not remove this member. It informs a compiler which
	automatically specializes __type_traits that this
	__type_traits template is special. It just makes sure that
	things work if an implementation is using a template
	called __type_traits for something unrelated. */

	/* The following restrictions should be observed for the sake of
	compilers which automatically produce type specific specializations
	of this class:
	- You may reorder the members below if you wish
	- You may remove any of the members below if you wish
	- You must not rename members without making the corresponding
	name change in the compiler
	- Members you add will be treated like regular members unless
	you add the appropriate support in the compiler. */


	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;
	typedef __false_type    is_POD_type;
};

因为我们的内置类型就那么几个,而用户自定义类型的可能多的数不过来. 自定义类型可能大部分都是__false_type. 所以我们

的SGI先把所有的类型 的五种萃取型别的特性定义为__false_type. 但是内置类型的五种萃取型别的特性基本为__true_type. 所以呢

,再对内置类型特化就解决掉这个问题.

// Provide some specializations.  This is harmless for compilers that
//  have built-in __types_traits support, and essential for compilers
//  that don't.

__STL_TEMPLATE_NULL 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;
   typedef __true_type    is_POD_type;
};

__STL_TEMPLATE_NULL struct __type_traits<signed 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;
   typedef __true_type    is_POD_type;
};

__STL_TEMPLATE_NULL struct __type_traits<unsigned 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;
   typedef __true_type    is_POD_type;
};

__STL_TEMPLATE_NULL struct __type_traits<short> {
   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;
};

__STL_TEMPLATE_NULL struct __type_traits<unsigned short> {
   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;
};

__STL_TEMPLATE_NULL 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;
   typedef __true_type    is_POD_type;
};

__STL_TEMPLATE_NULL struct __type_traits<unsigned 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;
   typedef __true_type    is_POD_type;
};

__STL_TEMPLATE_NULL struct __type_traits<long> {
   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;
};

__STL_TEMPLATE_NULL struct __type_traits<unsigned long> {
   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;
};

__STL_TEMPLATE_NULL struct __type_traits<float> {
   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;
};

__STL_TEMPLATE_NULL struct __type_traits<double> {
   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;
};

__STL_TEMPLATE_NULL struct __type_traits<long double> {
   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;
};

#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION

template <class T>
struct __type_traits<T*> {
   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;
};

#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */

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;
   typedef __true_type    is_POD_type;
};

struct __type_traits<signed 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;
   typedef __true_type    is_POD_type;
};

struct __type_traits<unsigned 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;
   typedef __true_type    is_POD_type;
};

__type_traits在SGI STL应用简直不要太广泛,我们单单的看源代码没有办法更好的理解它. 必须加一点实例. STL定义了5个函

数,他们内部都使用 了__type_traits. 我有一篇博客有源代码加图示来解释这5个函数,相信你了解懂这5个函数的时候,那么你一定

就深刻理解__type_traits的思想.

博客链接: 内存基本处理工具!!!!!!!!!!!!!!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值