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
个有着真/假性质的对
象,因为我们希望利用其响应结果来进行参数推导,而编译器只有面对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的思想.
博客链接: 内存基本处理工具!!!!!!!!!!!!!!