来看迭代器类型萃取机。
文件:stl_iterator_base.h
定义迭代器种类的五种类型,这五种类型不包含任何数据,只是用来作为参数传递给算法,
这时会根据编译器的函数重载来选择最合适的对迭代器的操作,比如,对一个迭代器加上n,
对于forword类型的,只能循环n次,一次加一,而对于random类型的,就可以一次+n,
这样可以提高效率。当设计迭代器的时候,选择这五种类型的一种
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
迭代器的类型萃取机。这个类可以提取出你想使用的类型。
要想使用这个萃取机,必须自己在定义迭代器的时候,通过内嵌类型定义这些类型。
template
struct iterator_traits {
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};
上面的对于原生指针不可用,因此有了偏特化版本。
template
struct iterator_traits<_Tp*> {
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
template
struct iterator_traits {
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};
下面来看一个具体的迭代器类型设计:
文件: stl_list.h
struct _List_iterator_base {
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef bidirectional_iterator_tag iterator_category;
。。。。。。。。。。。。。。
}
template
struct _List_iterator : public _List_iterator_base {
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
typedef _List_iterator<_Tp,_Ref,_Ptr> _Self;
typedef _Tp value_type;
typedef _Ptr pointer;
typedef _Ref reference;
。。。。。。。。。。。。。。。。。
}
这样,每种迭代器类型,在自己的类内,通过内嵌类型定义,然后使用公用的迭代器萃取机,方便的提取相应的类型。如下图所示:
上面介绍是负责萃取迭代器的类型。还有一种负责萃取类型的特性。
比如:你要数组copy(copy是个模板函数)时,假如你存的是int类型,就可以直接memcpy或者memmove,
但是若是类类型对象,你还要调用构造函数。这样可以通过萃取类型,在编译时期通过函数重载确定选用什么复制类型,来加快操作。
eg:
template inline void copy(T* source,T* destination,int n) {
copy(source, destination, n, typename __type_traits::has_trivial_copy_constructor()); 函数重载
}
template void copy(T* source, T* destination, int n, __false_type){}; 通过两种不同的类类型来重载。
template void copy(T* source, T* destination, int n, __true_type){};
文件:type_traits.h
struct __true_type {
};
struct __false_type {
};
默认自定义的类类型,都是 non-tivial的。你自己可以自己设定,一般如果类的内部含有指针成员,并且对它进行内存动态分配,这种类一般就要实现自己的non-trivial-xxx
template
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_TEMPLATE_NULL struct __type_traits {
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 {
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
struct __type_traits<_Tp*> {
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 {
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;
};
。。。。。。。。。。。。。。。。还有好多偏特化,就不一一列举了。