STL源码分析之__type_traits
来源:互联网 发布:axure for mac 汉化包 编辑:程序博客网 时间:2024/06/06 16:18
之前我们对iterator_traits有了一些了解,现在我们要了解__type_traits。
Iterator_traits负责萃取迭代器的特性,__type_traits则负责萃取型别的特性。
对于型别的特性,我们关注的点可能在于对该型别是否需要复杂处理。如果答案是否定的,我们在对这些型别进行构造、析构、拷贝赋值等操作时,就可以采取最有效率的措施,比如不使用析构函数,直接free等。
__type_traits提供了一种机制,允许针对不同的型别属性,在编译时期完成函数派送决定。这对于撰写template很有帮助。例如当我们对一个型别未知的数组进行copy时,如果我们事先知道该元素型别的构造函数是否是不重要的,我们可能可以使用memcpy或是memmove等函数快速处理
根据之前对于iterator_traits的学习,我们想必是希望与其有相同的形式可以使用:
__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类型的值,可以帮助我们实现重载
struct __true_type {};struct __false_type {};
STL对最初的__type_traits是这样处理的:
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_operator; typedef __false_type has_trivial_destructor; typedef __false_type is_POD_type;};
STL将所有类型的内嵌型别都定义为__false_type,这事STL给出的保守值,接下来我们会看到针对每一个型别设计的适当的__type_traits的特化版本
以下仅列出两个,其他类型的省略:
__STL_TEMPLATE_NULLstruct __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;};
//对于原生指针template <class T>struct__type_traits<T*> { 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;};
接下来,我们拿几个例子看看uninitialized_fill_n
首先,我们来看看全局函数
template <class ForwardIterator, class Size, class T>inline ForwardIteratoruninitialized_fill_n(ForwardIterator first, Size n, const T& x) { return __uninitialized_fill_n(first, n, x, value_type(first));}
此函数在关于空间配置器的章节中见到过,用途也不多说了,就是在未初始化的空间内初始化n个x
可以看到,这里我们首先通过value_type(其实就是通过iterator_traits)得到了first类型中的value_type,即first的型别
接着:
template <class ForwardIterator, class Size, class T, class T1>inline ForwardIterator__uninitialized_fill_n(ForwardIterator first, Size n, const T& x, T1*) { typedef typename __type_traits<T1>::is_POD_type is_POD; return __uninitialized_fill_n_aux(first, n, x, is_POD()); }
再通过__type_traits得到该型别是否是POD类型
//如果正是POD类型的话,只要简单的操作template <class ForwardIterator, class Size, class T>inline ForwardIterator__uninitialized_fill_n_aux(ForwardIteratorfirst, Size n, const T& x,__true_type) { return fill_n(first, n, x);}template <class OutputIterator, class Size, class T>OutputIteratorfill_n(OutputIterator first, Size n, const T& value) { for ( ; n > 0; --n, ++first) *first = value; return first;}
//如果不是POD类型,那么就需要老老实实的一个一个在未初始化的内存中调用构造函数了!template <class ForwardIterator, class Size, class T>ForwardIterator__uninitialized_fill_n_aux(ForwardIteratorfirst, Size n, const T& x,__false_type) { ForwardIterator cur = first; __STL_TRY { for ( ; n > 0; --n, ++cur) construct(&*cur, x); return cur; } __STL_UNWIND(destroy(first, cur));}
再举一个例子,就是copy函数
最近一篇文章就是关于copy函数的笔记,所以详细的部分不再说了。
这里直接放在实例中进行:
class C{public: //可见,此函数并没有operator= ,即it is a trival assignmentoperator C() :_date(3){}private: int _date;}; void main(){ C c[5]; vector<C> Cc(c, c + 5); vector<C> Cd(5); copy(Cc.begin(), Cc.end(), Cd.begin());}
回顾之前对copy的学习,我们发现,对于copy内的函数调用的顺序是:
copy() ----- __copy_dispatch(T*, T*) ----- __copy_t(_false_type) ----- __copy_d
会调用__copy_dispatch(T*,T*)是因为在vector源代码中将iterator定义为类型的指针,并没有做任何处理。
然而为什么会是false_type呢?我们根据类的定义,根据语义,发现的确满足“具有不重要的assignmentoperator”,但返回的结果却依旧是false_type?
学了copy函数后,我们可能会对此感到疑惑,但当我们学过了本章__type_traits的源代码后,我们就可以清楚了知道,STL只对基础的型别进行了偏特化的处理,然而对于其他的型别则一律给予false_type的处理,除非我们自己定义这里类C的__type_traits,如下:
__STL_TEMPLATE_NULLstruct __type_traits<C> { typedef __false_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 __false_type is_POD_type;};
这样一来,如果再次执行,那么就是true_type了!
- STL源码分析之__type_traits
- 【STL源码剖析】__type_traits技法
- STL之__normal_iterator和__type_traits
- STL源码分析之感想
- STL源码分析之Vector
- STL源码分析之Vector
- STL之pair源码分析
- STL源码分析之大顶堆
- STL源码分析之hashtable
- STL 神奇的__type_traits (转
- STL 源码分析 之 rotate()函数分析
- 《STL源码剖析》学习笔记2——神奇的__type_traits
- 《STL源码剖析》之vector分析
- 《STL源码剖析》之vector分析
- STL源码分析之vector容器
- STL源码分析之power算法
- STL源码分析之 sort算法
- STL源码分析之copy算法
- finishOpenedActivities 空指针
- 使用Embed标签在AS3项目中嵌入字体(转自http://zengrong.net/post/1438.htm)
- 萃取(traits)编程技术的介绍和应用
- iOS App各种路径
- 群策CRM全新出击,让手机端与PC端展现良性互通
- STL源码分析之__type_traits
- pypi本地源的搭建
- 一只在读iOS菜鸟十个月来从零基础到拿到实习Offer的总结
- Linux云服务器安装JDK步骤
- Servlet--HttpServletRequest接口,HttpServletResponse接口
- 修正CGBitmapContextCreate iOS8上的错误
- 点击扫描仪老提示操作无法完成(0x00000015 )设备未就绪
- 设置notepad++默认以utf-8格式保存
- Yii中relations里配置和一些个人经验