文章目录
type_traits概念
iterator_traits负责萃取迭代器的特性, __type_traits负责萃取型别(type)的特性。
此处我们所关注的型别特性是指:
这个型别是否具备non-trivial defalt ctor?
是否具备non-trivial copy ctor?
是否具备non-trivial assignmentoperator?
是否具备non-trivial dtor?
如果答案是否定的,我们在对这个型别进行构造、析构、拷贝、赋值等操作时,就可以采用最有效率的措施(例如根本不调用身居高位,不谋实事的那些constructor,destructor ),而采用内存直接处理操作如malloc ( )、memcpy ()等等,获得最高效率。这对于大规模而操作频繁的容器,有着显著的效率提升。
根据iterator_traits得来的经验,我们希望,程序之中可以这样运用__type_traits,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 的做法:
template <class type>
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
/*不要移除这个成员。它通知“有能力自动将__type_traits 特化”的编译器说,
我们现在所看到的这个_type_traits template是特殊的。
这是为了确保万一编译器也使用一个名为__type_traits而其实
与此处定义并无任何关联的template 时,所有事情都仍将顺利运作*/
/*以下条件应被遵守,因为编译器有可能自动为各型别产生专属的__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;
typedef __false_type is_POD_type;
};
上述__type_traits 可以接受任何型别的参数,五个typedefs将经由以下管道获得实值:
- 一般具现体( general instantiation),内含对所有型别都必定有效的保守值。上述各个has_trivial_xxx型别都被定义为__false_type,就是对所有型别都必定有效的保守值。
- 经过声明的特化版本,例如<type_traits.h>内对所有C++标量型别( scalar types)提供了对应的特化声明。
- 某些编译器(如Silicon Graphics N32和 N64编译器)会自动为所有型别提供适当的特化版本。
代码
对内置类型提供特化版本
#ifndef MY_TYPE_TRAITS_H
#define MY_TYPE_TRAITS_H
namespace Srh
{
struct __true_type {};
struct __false_type {};
template<typename type>
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
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;
};
// 特化版本
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;
typedef __true_type is_POD_type;
};
template<> 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;
};
template<> 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;
};
template<> 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;
};
template<> 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;
};
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;
typedef __true_type is_POD_type;
};
template<> 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;
};
template<> struct __type_traits<long 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;
};
template<> struct __type_traits<unsigned long 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;
};
template<> struct __type_traits<long 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;
};
template<> struct __type_traits<unsigned long 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;
};
template<> 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;
};
template<> 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;
};
template<> 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;
};
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;
};
}
#endif
END
参考自《STL源码剖析》