C++ Traits
STL 偏特化设计
概念:如果class template 中存在一个或者多个template参数,可以针对其中某个或者几个,但不是全部的template参数进行特化工作。
- 迭代器型别 value_type,指的是迭代器所指的对象的型别
typedef T value_type
- difference_type 表示两个迭代器之间的距离,可以用来表示一个容器的最大容量(连续空间上,头尾之间的距离),stl中的count(),表示的结果就是difference_type
typedef typename T::difference_type difference_type 一般情况 typedef ptrdiff_t difference_type 原生指针 //任何时候需要任何迭代器I 的difference_type 可以写成 typename iterator_traits<I>::difference_type
- reference type 引用类型
typedef T& reference;
- pointer type 指针类型
typedef T& pointer;
- iterator_category; 标记类型
typedef xxx_iterator_tag iterator_category;
例如:
template <class Iterator>
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;
};
注意点:
-
设计了五个标签:
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 <class InputIterator, class Distance> inline void __advance(InputIterator& i, Distance n, input_iterator_tag) { //逐一前进 while (n--) ++i; } template <class BidirectionalIterator, class Distance> inline void __advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag) { if (n >= 0) while (n--) ++i; else while (n++) --i; } template <class RandomAccessIterator, class Distance> inline void __advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag) { i += n; }
以及计算两个迭代器的distance()函数
-
以上两者诠释了迭代器分为五类的设计与应用,利用iterator_traits,将迭代器萃取出来,结果就是讲类似的进行标记,然后通过各个iterator_traits形式通过内嵌的类型,和template进行参数推导,尤其是iterator_category等提取验证
-
taits,通过将类型等信息声明为局部变量,对外接口func,实际操作有funcImpl执行,根据funcImpl的参数类型进行推导,没有返回值的易于理解处理,可以直接通过参数个数,参数诶下进行处理 模板参数类型推导
template<typename Iterator>
typename Iterator::value_type //返回类型
function(Iterator iter)
{
return *iter;
}
//通过iterator_traits作用后的版本
template<typename Iterator>
typename iterator_traits<Iterator>::value_type //返回类型
function(Iterator iter)
{
return *iter;
}
利用typename告诉编译器这是个类型,保证编译顺利,指针没办法进行定义内嵌的类型(value_type等)通过特化处理,就是直接将<T*>进行替代<T>进行特化处理
- 继承迭代处理
template <typename T>
class ListIter : public std::iterator<std::forward_iterator_tag, T>
{
}
标记登记:
- 标记目标函数(一般模板)具备的特性,返回类型,传入类型类别
- 登记目标函数(特化模板)传入参数的特征,返回特征,返回标记
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;
};
has_trivial_xxx:判断准则:class内含指针成员,并且对改成员进行了内存动态配置,分配的操作类型判定has_trivial_xxx