traits编程技法利用了“内嵌型别”的编程技巧与编译器的template参数推导功能。
下面主要看看利用traits编程技法实现的迭代器萃取机制。
5种迭代器类型定义:
struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterarot_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterarot_tag {};
std::iterator的定义
template <class Category, class T, class Distance = ptrdiff_t, class Pointer = T*, class Reference = T&> struct iterator { typedef Category iterator_category; typedef T value_type; typedef Distance difference_type; typedef Pointer pointer; typedef Reference reference; };
如果想和STL协同工作,自行定义的迭代器必须定义iterator_category、value_type、difference_type、pointer、reference这五大内嵌型别。为了方便,STL定义了std::iterator这个基类,自定义的迭代器只要继承这个基类
就可以了。但要注意的是,并不是STL中的所有迭代器都继承了这个基类,比如_deque_iterator。
"榨汁机"traits
template <class Iterator> struct iterator_traits { typedef typename Iterator::iterator_category iterator_category; typedef typename Itetator::value_type value_type; typedef typename Iterator::difference_type difference_type; typedef typename Iterator::pointer pointer; typedef typename Iterator::reference reference; };
由于原生指针也是一种迭代器,但是原生指针没有内嵌型别,因此,iterator_traits需要为原生指针提供特化版本。
template <class T> struct iterator_traits<T*> { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; }; template <class T> struct iterator_traits<const T*> { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef const T* pointer; typedef const T& reference; };