STL学习_萃取技术__type_traits

之前在学习STL库中的析构工具destory()时,提到过这样一句话,此函数设法找到元素的数值型别,进而利用__type_traits<>求取适当措施。一直难以理解,现在自己总结了下自己对萃取技术的理解。

让自己困惑的程序:

template<class T>

void destroy(T *pointer)

{

pointer->~T();

}

template<calss ForwardIterator>

void destroy(ForwardIterator first, ForwardIterator last)

{

__destroy(first, last, value_type(first));

}

template<class ForwardIterator, class T>

void __destroy(ForwardIterator first, ForwardIterator last, T*)

{

typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;

__destroy_aux(first, last, trivial_destructor());

}

//注意这里判断元素的数值型别是否有trivial destructor, 由于是__false_type,所以要对这个型别进行析构,所以

//轮询调用destroy()进行析构

template<class ForwardIterator>

void __destroy_aux(ForwardIterator first, ForwardIterator last,
__false_type)

{

for( ; first < last; ++first){

destroy(&*first);

}

}

//由于是__true_type所以不用进行析构操作,系统会采用内存直接处理操作例如free

template<class ForwardIterator>

void __destroy_aux(ForwardIterator first, ForwardIterator last,
__true_type)

{

}

这里有困惑,那么看看萃取机制

萃取技术,就是当函数,类这种一些封装的通用算法中的某些部分会因为数据类型不同而导致处理的逻辑不同,然而我们又不想因为数据类型的差异而修改算法本身的封装,所以采用萃取机制来解决这一问题。从而实现同一种操作因类型不同而异的效果。因此在STL中为了提供通用的操作而又不想损失效率就采用traits编程技巧。

__type_traits负责萃取型别特性,通常我们关注的型别特性有是否具备non-trivial defalt ctor?是否具备non-trivial copy ctor?是否具备non-trivial assignment operator?是否具备non-trivial dtor?如果答案是否定的(也就是说具备这些特性)就对这个型别进行构造,析构, 拷贝, 赋值等操作,这样可以采用最有效率的措施。(比如一些自己定义的类,或者不是普通类型比如string类,
对象等,就要进行这样的操作)如果答案是确定的(也就是说不具备这些特性,例如int, float. double, char等普通的类型就不具备这种特性)这些类型为了提高效率直接采用内存处理操作,例如malloc() memcpy(),所以这种机制对于大规模操作频繁的容器有着显著的效率的提升。

例如:我们准备对一个元素型别未知的数组进行拷贝操作,如果我们知道这个元素型别是否有一个trivial copy constructor,以便我们决定是否使用快速的memcpy(),还是使用慢速的拷贝构造函数。

  下面是SGI中<type_traits.h>中的__type_traits,提供的一种机制,允许针对不同型别属性,在编译期完成函数派送决定(意思是在编译期就决定是采用快速的内存直接处理操作还是采用慢速的构造,析构,拷贝,赋值操作)

struct __true_type{};

struct __false_type{};

template<calss type>

struct __type_traits{

typedef __true_type this_dummy_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;

};

SGI把所有的内嵌型别都定义为__false_type,定义出最保守的值。但同时SGI还针对每一个型别设计了适当的__type_traits的特化版本

例如:char类型,因为对char类型进行初始化,删除,赋值,复制,都可以通过快速的内存直接处理操作,所以这里将__false_type改为__true_type不具备这些特性。

__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;

}

了解这些,现在回头看看最上面那个之前看不懂的destroy()析构工具,目的是将[first, last)范围ie内的所有对象析构掉,我们不知道这个范围有多大,如果 很大,然而每个对象的析构函数都无关痛痒,那么一次次调用这些析构会哪数会降低效率,因此这里利用value_type()获得迭代器所指对象的型别,在利用__type_traits<T>判断该型别的析构函数是否无关痛痒,如果是__true_type则什么都不做,系统会采用内存直接处理操作,如果是__false_type才采用循环方式对每个对象进行析构。

时间: 2024-10-16 18:56:57

STL学习_萃取技术__type_traits的相关文章

STL源代码分析--萃取编程(traits)技术的实现

1.为什么要出现? 依照默认认定.一个模板给出了一个单一的定义,能够用于用户能够想到的不论什么模板參数!可是对于写模板的人而言,这样的方式并不灵活.特别是遇到模板參数为指针时,若想实现与类型的參量不一样的实例化.就变得不太可能了!也有时.想禁止此种同样的实例化变得不太可能! 故而出现了,Partial Specialization! 同一时候,在使用void*指针时.能够最大限度的共享代码,降低代码的膨胀! 2.它是什么?事实上,就是用户定义的偏特化.用template<>来说明这是一个偏特化

C++_模板类与类型萃取技术

在声明变量,函数,和大多数其他类型实体的时候,C++要求我们使用指定的类型.然而,有许多代码,除了类型不同之外,其余部分看起来都是相同的,比如,下面这个例子: bool IsEqual (int left, int right) {     return left == right; } bool IsEqual (const string& left , const string& right) {     return left == right; } void test() {   

迭代器与萃取技术

看了书和老师的讲解,这里大体说一下自己对迭代器和萃取技术的理解. 迭代器它是C++标准模板库里面的智能指针(smart pointer),由于STL设计时并不是以OOP思想为指导,而是以GP,所以让容器与算法分离实际,这么做的好处是可以让各个模块的设计者无需去关系其他模块的实现,从而专心于自己的模块,所以迭代器是用于连接容器和算法的桥梁. OOP(Object-Oriented programming)//面向对象的程序设计 GP(Generic Programming)//泛型程序设计 作为智

STL学习_配接器篇

STL学习_配接器篇 定义 配接器(Adapter)在STL组件的灵活组合运用功能上,扮演着轴承.转换器的角色.它事实上是一种设计模式.即将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作. 分类 STL所提供的各种适配器中,改变仿函数(functors)接口者,称为function adapter:改变容器(containers)接口者,称为container adapter:改变迭代器(iterators)接口者,称为iterato

STL(七)之萃取技术

traits技术 原理:利用template的参数推导机制获取传入的参数型别. template<typename T> struct Iter { typedef T value_type; .... } template<typename T> typename T::value_type func(T* ite) {return *ite;} 这种程度,依旧会遇到一个问题:如果不是一个class type(比如指针,引用),就无法进行正确的参数推导.可以使用模板偏特化来处理这

C++之萃取技术(traits)

为什么需要类型萃取 前面我们提到了迭代器,它是一个行为类似于smart pointer之类的东西,主要用于对STL容器中的对象进行访问,而且不暴露容器中的内部结构,而迭代器所指对象的型别称为该迭代器的value type;如果在实际的工程当中我们应该怎么获取STL容器中对象的value type 呢,这里面就需要用到C++中模板的特化了,我们先来看看下面的代码: template <class T> void Func() { cout << "非内置类型" &

Python学习_从文件读取数据和保存数据

position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位问题.所以当没有定义position属性时,并不说明该元素没有自己的位置,它会遵循默认显示为静态位置,在静态定位状态下无法通过坐标值(top,left,right,bottom)来改变它的位置. position:absolute(绝对定位) 当position属性定义为absolute时,元素会脱离文档流

HeadFirstPython学习_从文件读取数据和保存数据

运用Python中的内置函数open()与文件进行交互 在HeadFirstPython网站中下载所有文件,解压后以chapter 3中的"sketch.txt"为例: 新建IDLE会话,首先导入os模块,并将工作目录却换到包含文件"sketch.txt"的文件夹,如C:\\Python33\\HeadFirstPython\\chapter3 >>> import os >>> os.getcwd() #查看当前工作目录 'C:

STL源码分析--萃取编程(traits)技术的实现

1.为什么要出现? 按照默认认定,一个模板给出了一个单一的定义,可以用于用户可以想到的任何模板参数!但是对于写模板的人而言,这种方式并不灵活,特别是遇到模板参数为指针时,若想实现与类型的参量不一样的实例化,就变得不太可能了!也有时,想禁止此种相同的实例化变得不太可能!故而出现了,Partial Specialization! 同时,在使用void*指针时,可以最大限度的共享代码,减少代码的膨胀! 2.它是什么?其实,就是用户定义的偏特化.用template<>来说明这是一个偏特化,针对任何模板