STL中的traits机制
Traits技术是STL iterator设计中非常重要的一枚棋子,它主要依靠偏特化(template Partial Specialization)进行处理。比如
template<typename T>
struct MyClass {...};
它的一个偏特化形式可以为:
template<typename T>
struct MyClass<T*> {...};
当然还有其它形式的表达方法。
traits技术指的是,提供一个专门的class template来用于萃取特性。例如在stl中的iterator_traits,表现形式为:
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;
};
如果要设计一个对象,并使其能通过iterator_traits 进行萃取,必须在它的定义式里声明value_type等,例如list(对于int,double等变量,可以定义偏特化的traits):
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class list : protected _List_base<_Tp, _Alloc> {
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
...
}
traits中也可以定义函数,如《Traits技术:类型的if-else-then(STL核心技术之一)》,这篇文章在traits中定义了static函数以对traits出的不同类型做不同的处理。
下面是写的一个测试程序:
#include <iostream>
using namespace std;
struct T_tag {};
struct T_point_tag: public T_tag {};
template<typename T>
struct my_traits
{
typedef typename T::value_type value_type;
typedef typename T::value_catogry value_catogry;
};
template <class Tag, class T>
struct my_base
{
typedef Tag value_catogry;
typedef T value_type;
};
template <class T>
struct my_derived:public my_base<T_tag,T>
{
T value;
};
template <class T>
struct my_point_derived:public my_base<T_point_tag,T>
{
T* value;
};
template <class T>
typename my_traits<T>::value_type my_value(T t)
{
return t.value;
}
template<typename T>
typename my_traits<T>::value_type __f(T t1, T t2, T_tag)
{
return t1.value > t2.value?t1.value:t2.value;
};
template<typename T>
typename my_traits<T>::value_type __f(T t1, T t2, T_point_tag)
{
return *(t1.value) > *(t2.value)?*(t1.value):*(t2.value);
};
template<typename T>
typename my_traits<T>::value_type f(T t1, T t2)
{
typedef typename my_traits<T>::value_catogry catogray;
return __f(t1, t2, catogray());
};
int main()
{
int a = 9;
int b = 4;
my_derived<int> aa0; aa0.value = a;
my_derived<int> aa1; aa1.value = b;
my_point_derived<int> bb0; bb0.value = &a;
my_point_derived<int> bb1; bb1.value = &b;
cout << f< my_derived<int> >(aa0,aa1) << endl;
cout << f< my_point_derived<int> >(bb0,bb1) << endl;
cout << my_value<my_derived<int> >(aa0);
}