STL-迭代器中的traits
STL中算法通过迭代器访问容器时,有时不仅仅需要知道元素是什么,还想用到元素的相应类型(声明一个变量之类)。STL中利用traits编程技巧来实现。它通过在每一种迭代器中声明了类型名。再通过iterator_traits来萃取类型。最终通过iterator_traits来获取类型。
为什么要通过iterator_traits来获取类型?这是因为,原生指针无法声明类型名,无法直接通过指针来获取类型名。通过对iterator_traits的偏特化可以为原生指针提供类型名的接口。
如下:
//做了简化处理,实际在mingw 7.2.0 g++中,有继承一个base类,迭代器中本身就定义了类型
template<typename 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;
};
/// Partial specialization for pointer types.为指针做的偏特化版本
template<typename _Tp>
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;
};
NOTES:对于typename的说明,由于iterator是一个模板参数,在它被编译器具象化之前,编译对iterator一无所知,换句话说,编译器不知道Iterator::value_type代表的是一个类型或是一个成员函数或是一个数据成员。关键字typename的用意在于告诉编译器这是一个类型,如此才能通过编译。
traits的用法示例:
template<class InputIterator, class OutputIterator>
OutputIterator algorithm(InputIterator first, InputIterator last, OutputIterator result)
{
//定义一个迭代器所指类型的变量
typename iterator_traits<InputIterator>::value_type tmp ;
}