《STL源码剖析》——迭代器(iterators)概念与traits编程技法(二)

一、SGI STL 的私房菜:__type_traits

        __type_traits 负责萃取型别(type)的特性。此处所关注的型别特性是指:这个型别是否具备 non-trivial defalt ctor?是否具备 non-trivial copy ctor?是否具备 non-trivial assignment operator?是否具备 non-trivial dtor?如果答案是否定的,我们在对这个型别进行构造、析构、拷贝、赋值等操作时,就可以采用最有效率的措施,而采用内存直接处理操作,如malloc()、memcpy()等等,获得最高效率。

       根据 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

       我们希望上述式子相应我们“真”或“假”,但其结果不应该只是个 bool 值,应该是个有着真/假性质的“对象”,因为我们希望利用其响应结果来进行参数推导,而编译器只有面对 clas object 形式的参数才会做参数推导。为此,上述式子应该传回这样的东西:

       struct  __true_type { };

       struct  __false_type { };


       为了达成上述五个式子,__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 将经由一下管道获得实值:

        1. 一般具现化,内含对所有型别都必定有效的保守值。

        2. 经过声明的特化版本,例如<type_traits.h>内对所有 C++ 标量型别提供了对应的特化声明。

        3. 某些编译器会自动为所有型别提供适当的特化版本。


你可能感兴趣的:(C++,源码,STL)