《STL 源码剖析》——__type_traits源码剖析

本文详细剖析了STL中的__type_traits设计和实现,包括其在标量、全局函数uninitialized_copy和uninitialized_fill_n()中的应用。通过__type_traits,可以高效地处理不同类型,特别是POD数据类型的拷贝和初始化。对于不支持type_traits的编译器,需要手动为类进行特化以确保正确的行为。
摘要由CSDN通过智能技术生成

萃取机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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三公子Tjq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值