萃取机traits不仅可以萃取迭代器iterators_traits的型别,还可以萃取type_traits型别。即iterator_traits萃取迭代器特性,而_type_traits萃取型别特性。此处我们关心的型别是指:是否具备non-trivial defalt ctor?是否具备non-trivial copy ctor?是否具备non-trivial assignment?是否具备non-trivial dtor?如果答案是肯定的,我们就可以对这个型别进行构造、析构、拷贝、赋值等操作时采用最有效率措施,即直接采用内存直接处理操作,比如用malloc()、memcpy()等等进行逐字节操作。
一、__type_traits设计和实现
1.1__type_traits类设计
特性萃取机__type_traits主要有五个特性,如下代码所示:
struct __true_type {
};
struct __false_type {
};
template <class 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_constructor;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type; // Plain Old Data
};
类型特性萃取机__type_traits设计代码如上所示,其五个typedefs将由以下方法获得实质:
- 一般具现体(gneral instantiation),内含对所有型别都有效的保守值,比如上述定义都为__false_type 就是保守值;
- 经过声明的特化版本,比如<type_traits.h>内对所有C++标量型别提供了对应的特化声明,如文末附录代码所示。
- 某些编译器(如SIlicon Graphics N32 和 N64 编译器)会自动为所有型别提供适当的特化版本;
1.2 __type_traits应用
__type_traits在SGI STL大量应用,比如在标量和五个全局函数中。
1.2.1应用在标量中
当__type_traits为C++基本型别char、signed char、unsigned char、short、unsigned short、int、unsigned int、long、unsigned long、float、double、long double提供特化版时,每一个成员的值都是__true_type,即如下代码的型别可以采用最快方式(如memory)进行逐字节拷贝(copy)或者赋值(assign)
__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<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;
};
1.2.2 __type_traits应用在全局函数uninitialized_copy中
全局函数__uninitialized_copy()中通过__type_traits<_Tp1>::is_POD_type利用模板在编译时编译器自动推导功能萃取出POD数据型别,然后自动调用__uninitialized_copy_aux(_ForwardIter __first, _Size __n,const _Tp& __x, __true_type)或者__uninitialized_copy_aux(_ForwardIter __first, _Size __n,const _Tp& __x, __false_type)对内存进行拷贝或移动操作。
最后两个类inline char* uninitialized_copy(const char* __first, const char* __last, char* __result)和inline wchar_t*
uninitialized_copy(const wchar_t* __first, const wchar_t* __last, wchar_t* __result)是const char* 和wchar_t* 的特化版本,因为都是标量,所以直接进行高效率的逐字节拷贝。
// uninitialized_copy
// Valid if copy construction is equivalent to assignment, and if the
// destructor is trivial.
template <class _InputIter, class _ForwardIter>
inline _ForwardIter
__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
_ForwardIter __result,
__true_type)
{
return copy(__first, __last, __result);
}
template <class _InputIter, class _ForwardIter>
_ForwardIter
__uninitialized_copy_aux(_InputIter __first, _InputIter __last,
_ForwardIter __result,
__false_type)
{
_ForwardIter __cur = __result;
__STL_TRY {
for ( ; __first != __last; ++__first, ++__cur)
_Construct(&*__cur, *__first);
return __cur;
}
__STL_UNWIND(_Destroy(__result, __cur));
}
template <class _InputIter, class _ForwardIter, class