traits 技术
原理: 利用 template 的参数推导机制获取传入的参数型别.
- template<typename T>
- struct Iter
- {
- typedef T value_type;
- ....
- }
- template<typename T>
- typename T::value_type func(T* ite)
- {return *ite;}
这种程度, 依旧会遇到一个问题: 如果不是一个 class type(比如指针, 引用), 就无法进行正确的参数推导. 可以使用模板偏特化来处理这种情形:
- template<typename T>
- struct Iter<T*>
- {
- typename T value_type;
- };
我们需要处理的核心问题: 通过 traits 技术如何获得 iterator 描述的型别?
- template<typename T>
- struct iterator_traits
- {
- typedef typename T::iterator_category iterator_category;
- typedef typename T::value_type value_type;
- typedef typename T::difference_type difference_type;
- typedef typename T::pointer pointer;
- typedef typename T::reference reference;
- };
同时, iterator_traits 必须对传入的型别为 pointer 和 pointer-to-const 者设计特化版本.
- template<typename T>
- struct iterator_traits<T*>
- {
- ...
- typedef random_access_iterator_tag iterator_category;
- }
- template<typename T>
- struct iterator_traits<const T*>
- {
- ...
- typedef random_access_iretator_tag iterator_category;
- }
型别:
value type: 描述 iterator 指向对象的型别.
difference type: 描述两个 iterator 之间的距离, 默认情况下使用 C++ 内建的 ptrdiff_t 类型
reference type: 描述 iterator 所指向对象的引用
pointer type: 描述 iterator 所指向对象的指针
iterator_category: 描述迭代器的相应性别
Input Iterator: 只读迭代器
Output Iterator: 只写迭代器
Forward Iterator: 读写迭代器
Bidirectional Iterator: 双向移动迭代器, 可读写
Random Access Iterator: 随机移动迭代器, 可读写
利用重载机制, 通过在编译期就为不同版本的迭代器选择不同版本的函数:
- template<typename category,typename T,typename dis=ptrdiff_t,typename poin=T*,typename ref=T&>
- struct iterator
- {
- typedef category iterator_category;
- typedef T value_type;
- typedef dis difference_type;
- typedef poin pointer;
- typedef ref 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 <typename InputIterator,typename Distance>
- inline void __advance(InputIterator& iter,Distance n,input_iterator_tag)
- {
- while(n--)
- ++iter;
- }
- template <typename ForwardIterator,typename Distance>
- inline void __advance(ForwardIterator& iter,Distance n,forward_iterator_tag)
- {
- __advance(i,n,input_iterator_tag());
- }
- template <typename BidirectionalIterator,typename Distance>
- inline void __advance(BidirectionalIterator& iter,Distance n,bidirectional_iterator_tag)
- {
- if(n> 0)
- while(n--)
- ++iter;
- if(n <0)
- while(n--)
- --iter;
- }
- template <typename RandomAccessIterator,typename Distance>
- inline void __advance(RandomAccessIterator& iter,Distance n,random_access_iterator_tag)
- {
- iter += n;
- }
根据 traits 机制, 需要使用以下 的包装器:
- template <typename InputIterator,typename Distance>
- inline void __advance(InputIterator& iter,Distance n)
- {
- __advance(i,n,iteratir_traits<InputIterator>::iterator_category());
- }
获取型别的函数:
- template<typename Iterator>
- inline typename iterator_traits<Iterator>::iterator_category iteratir_category(const Iterator&)
- {
- typedef typename iterator_traits<Iterator>::iterator_category category;
- return category();
- }
- template<typename Iterator>
- inline typename iterator_traits<Iterator>::distance_type* distance_type(const Iterator&)
- {
- return static_cast<typename iterator_traits<Iterator>::distance_type*>(0);
- }
- template<typename T>
- inline typename iterator_traits<Iterator>::value_type* value_type(const Iterator&)
- {
- return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
- }
总结
设计适当的型别, 是迭代器的责任.
设计适当的迭代器, 是容器的责任.
__type_traits
traits 技术弥补了 C++ 语言本身的不足, 但是 traits 技术不仅存在于 Iterator 之中, 也存在于 STL 之中. iterator_traits 负责萃取迭代器特性,__type_traits 则负责萃取型别参数. 此处的型别参数是指: 这个型别是否具有 non-trivial default ctor? 是否具有 non-trivial copy ctor? 是否具有 non-travial assignment operator? 是否具有 non-trravial dctor? 如果没有的话, 我们可以使用 memcpy(),memmove()采取最有效的操作. 否则的话, 需要根据 ctor,copy,dctor 等进行复杂的操作.
可以使用如下类似与 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
- struct __true_type {};
- struct __false_type {};
- template<typename T>
- struct __type_traits
- {
- 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 为所有的内嵌性别定义最保守的值, 然后再为体统提供类型 (char,long,int,double) 等设计适当的特化版本.
- __STL_TEMPLATE_NULL struct __type_traits<bool> {
- 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;
- };
- #endif /* __STL_NO_BOOL */
- __STL_TEMPLATE_NULL struct __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;
- };
- __STL_TEMPLATE_NULL struct __type_traits<signed 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;
- };
- __STL_TEMPLATE_NULL struct __type_traits<unsigned 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;
- };
- #ifdef __STL_HAS_WCHAR_T
- __STL_TEMPLATE_NULL struct __type_traits<wchar_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;
- };
- #endif /* __STL_HAS_WCHAR_T */
- __STL_TEMPLATE_NULL struct __type_traits<short> {
- 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<unsigned short> {
- 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<int> {
- 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<unsigned int> {
- 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<long> {
- 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<unsigned long> {
- 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;
- };
- #ifdef __STL_LONG_LONG
- __STL_TEMPLATE_NULL struct __type_traits<long long> {
- 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<unsigned long long> {
- 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;
- };
- #endif /* __STL_LONG_LONG */
- __STL_TEMPLATE_NULL struct __type_traits<float> {
- 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<double> {
- 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<long double> {
- 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;
- };
- #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
- template <class _Tp>
- 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;
- };
- #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
- __STL_TEMPLATE_NULL struct __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;
- };
- __STL_TEMPLATE_NULL struct __type_traits<signed 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;
- };
- __STL_TEMPLATE_NULL struct __type_traits<unsigned 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;
- };
- __STL_TEMPLATE_NULL struct __type_traits<const 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;
- };
- __STL_TEMPLATE_NULL struct __type_traits<const signed 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;
- };
- __STL_TEMPLATE_NULL struct __type_traits<const unsigned 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;
- };
来源: http://www.bubuko.com/infodetail-2647101.html