c++ STL __type_traits<T>解释

今天看《STL源码剖析》,突然看到一个叫__type_traits<T>的名词。

当容器进行范围destoy的时候,其函数接受first和last的迭代器,若[first,last)范围内所有的元素都调用析构函数,但这个类型T的析构又是无关痛痒的,则会损耗效率。  __type_trais<T>可以判别该类型T的的析构函数是否无关痛痒,若是(__true_type),则什么都不做,否则调用其析构函数。

STL的destroy函数原型:

步骤解释:

1.首先容器触发destroy(Iterator first, Iterator last)

2.value_type(first)取得容器当前存储的类型T*,然后调用__destroy(Iterator first, Iterator last, T*)

3.在__destroy函数里, 利用typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor, 判断类型T的析构是否存在特性,并调用__destroy_aux,传入trivial_destructor

(若类型T是无特性的,其会定义typedef __true_type has_trivial_destructor, 否则定义typedef __false_type has_trivial_destructor)

4.若存在特性,则会调用到__destroy_aux(Iterator, Iterator, __false_type), 并逐一对[first, last)范围内的元素进行析构

5.若不存在特性,则会调用到__destroy_aux(Iterator, Iterator, __true_type), 并什么都不做

ps:更具体的理解可以看看http://blog.csdn.net/sanlongcai/article/details/1786647     该博文浅显地讲出了type trait的概念,而其测试代码也很容易懂。

此处顺便记录下本人对上述博文的测试代码的修改测试,供日后回味。 :)

 1 #ifndef TEST_CLASS_H
 2 #define TEST_CLASS_H
 3
 4 #include <iostream>
 5 using std::cout;
 6 using std::endl;
 7
 8 class TestClass
 9 {
10 public:
11     TestClass()
12     {
13         cout << "TestClass constructor call" << endl;
14         data = new int(3);
15     }
16     TestClass(const TestClass& test_class)
17     {
18         cout << "TestClass copy constructor call. copy data:"
19             << *(test_class.data) << endl;
20         data = new int;
21         *data = *(test_class.data) * 2;
22     }
23     ~TestClass()
24     {
25         cout << "TestClass destructor call. delete the data:" << *data << endl;
26         delete data;
27     }
28 private:
29     int *data;
30 };
31
32 #endif

TestClass.h

 1 // my_type_traits.h开始
 2 #ifndef MY_TYPE_TRAITS_H
 3 #define MY_TYPE_TRAITS_H
 4
 5 //#include "test_class.h"
 6
 7 struct my_true_type {
 8 };
 9
10 struct my_false_type {
11 };
12
13 template <class T>
14 struct my_type_traits
15 {
16     typedef my_false_type has_trivial_destructor;
17 };
18
19 template<> struct my_type_traits<int>
20 {
21     typedef my_true_type has_trivial_destructor;
22 };
23
24 //template<> struct my_type_traits<TestClass>
25 //{
26 //    typedef my_true_type has_trivial_destructor;
27 //}; //若删除对TestClass的注释,则TestClass将会被定义成没有特性的析构的类
28
29 #endif
30 // my_type_traits.h结束

my_type_traits.h

 1 // my_destruct.h开始
 2 #ifndef MY_DESTRUCT_H
 3 #define MY_DESTRUCT_H
 4 #include <iostream>
 5
 6 #include "my_type_traits.h"
 7
 8 using std::cout;
 9 using std::endl;
10
11 template <class T1, class T2>
12 inline void myconstruct(T1 *p, const T2& value)
13 {
14     new (p) T1(value);
15 }
16
17 template <class T>
18 inline void mydestroy(T *p)
19 {
20     typedef typename my_type_traits<T>::has_trivial_destructor trivial_destructor; //此处获得类型T是否没有特性析构
21     _mydestroy(p, trivial_destructor());
22 }
23
24 template <class T>
25 inline void _mydestroy(T *p, my_true_type)
26 {
27     cout << " do the trivial destructor " << endl;
28 }
29
30 template <class T>
31 inline void _mydestroy(T *p, my_false_type)
32 {
33     cout << " do the real destructor " << endl;
34     p->~T();
35 }
36
37 #endif
38 // my_destruct.h结束

my_destruct.h

 1 #include "test_class.h"
 2 #include "my_destruct.h"
 3
 4 int main(void)
 5 {
 6     {
 7         TestClass *test_class_buf;
 8         TestClass test_class;
 9
10         test_class_buf = (TestClass *)malloc(sizeof(TestClass));
11         myconstruct(test_class_buf, test_class);
12         mydestroy(test_class_buf);
13         free(test_class_buf);
14     }
15
16     {
17         int *int_p;
18         int_p = new int;
19         mydestroy(int_p);
20         free(int_p);
21     }
22 }

main.cpp

该图是当my_type_traits.h中对TestClass的has_trivial_destructor定义为__true_type的语句注释后的结果

下图则是未注释的结果

时间: 2024-10-10 04:32:29

c++ STL __type_traits<T>解释的相关文章

STL源码剖析——Iterators与Traits编程#5 __type_traits

上节给出了iterator_traits以及用到traits机制的部分函数的完整代码,可以看到traits机制能够提取迭代器的特性从而调用不同的函数,实现效率的最大化.显然这么好的机制不应该仅局限于在STL里面使用,在前某一节中我们也有说到,traits机制能够萃取类的特性,而这个类分为两个类别,一是迭代器类,二普通类,迭代器类我们已经有所了解了,那么本节就来学习负责萃取普通类型特性的__type_traits吧. 于普通类型而言,我们所关注的特性是指:这个类型是否具备non-trivial d

STL学习_萃取技术__type_traits

之前在学习STL库中的析构工具destory()时,提到过这样一句话,此函数设法找到元素的数值型别,进而利用__type_traits<>求取适当措施.一直难以理解,现在自己总结了下自己对萃取技术的理解. 让自己困惑的程序: template<class T> void destroy(T *pointer) { pointer->~T(); } template<calss ForwardIterator> void destroy(ForwardIterato

stl中顺序性容器,关联容器两者粗略解释

什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象,当然这是一个朴素的理解,这种"对象"还包含了一系列处理"其它对象"的方法,因为这些方法在程序的设计上会经常被用到,所以容器也体现了一个好处,就是"容器类是一种对特定代码重用问题的良好的解决方案". 容器还有另一个特点是容器可以自行扩展.在解决问题时

STL之set具体解释(二)

首先来看看set集合容器: set集合容器实现了红黑树的平衡二叉树数据结构.在插入元素时它会自己主动调整二叉树的排列,把该元素放到适当的位置,而且 保证左右子树平衡.平衡二叉检索树採用中序遍历算法. 对于set,vector,map等等,它们的前向迭代器定义是这种(以set为例): set<int>::iterator it; for(it=s.begin();it!=s.end();it++){} 那么反向迭代器呢? set<int>::reverse_iterator rit;

stl源码剖析学习笔记(二)traits编程技法简明例程

解释说明 traits侯捷老师的翻译是萃取.其目的就是在编译期进行模板调用的类型识别,从而做一些事情. 最突出的例子,我觉得不是<STL源码剖析>中"迭代器概念与traits编程技法"这一章的说明,而是stl算法中copy的实现.代码在stl源码的stl_algobase.h中. copy的最终实现,大致分为两类,一类是直接整块内存的memmove操作,另一类是一个个对象赋值.其中涉及has_trivial_assignment_operator的类型推断. 如果has_t

自己动手实现STL 03:内存基本处理工具(stl_uninitialized.h)

一.前言 前面两篇已经编写了内存配置器和建构解构工具函数.这里,就准备编写并介绍下内存基本处理工具函数.比如uninitialized_copy().uninitialized_copy和 uninitialized_copy_n()等的实现. 二.内存工具函数简介 1.uninitialized_copy函数 uninitialized_copy()使我们能够将内存的配置与对象的建构行为分离开来.如果作为输出目的地的[result, result+(last-first))范围内的每一个迭代器

C++STL内存配置的设计思想与关键源码分析

说明:我认为要读懂STL中allocator部分的源码,并汲取它的思想,至少以下几点知识你要了解:operator new和operator delete.handler函数以及一点模板知识.否则,下面你很可能看不大明白,补充点知识再学习STL源码比较好. 下面会结合关键源码分析C++STL(SGI版本)的内存配置器设计思想.关键词既然是“思想”,所以重点也就呼之欲出了. 1.allocator的简短介绍 我阅读的源码是SGI公司的版本,也是看起来最清楚的版本,各种命名最容易让人看懂.alloc

c++ STL容器初探

什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象,当然这是一个朴素的理解,这种"对象"还包含了一系列处理"其它对象"的方法,因为这些方法在程序的设计上会经常被用到,所以容器也体现了一个好处,就是"容器类是一种对特定代码重用问题的良好的解决方案". 容器还有另一个特点是容器可以自行扩展.在解决问题时

stl源码剖析 详细学习笔记 算法(1)

//---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都作用在由迭代器[first,last)所标示出来的区间上.质变算法 就是 运算过程会更改区间内的元素内容 非质变算法:和质变算法相反 */ /* stl算法的一般形式 1>所有的泛型算法的前两个参数都是一对迭代器,通常称为first和last,用以标示算法的操作区间 2>stl习惯采用前闭后开区间