STL中关于类型提取器的详细介绍,我再此就不赘述了,只是记下其中关键部分,供我以后学习之用。
nested type,这种方法能获得一个类的associated type,如下代码中,想要获得myIter类的T类型,可以在此类中nested一个typedef,将T保存下来,其他类中,就可以使用typename I::value_type来获得I类中nested进去的type(typename的作用就是告诉编译器I是一个类,不然无法通过编译)。
template <class T >
struct myIter
{
typedef T value_type ;
T *
ptr;
ptr;
myIter( T * p =
0):ptr( p){}
0):ptr( p){}
T&
operator*()
operator*()
{
return *ptr;
}
};
template <class I >
typename I ::value_type
func( I ite)
{
func_aux( ite,
* ite);
* ite);
return * ite;
}
当myIter如果是一个特别版本,比如一个原生指针(也可以看作一个迭代器),我们就无法拿到他的nested type,因为他是基本类型,根本就没有template,所以没有定义nested type。这样的话就要使用template
partial specialization(偏特化)。
partial specialization(偏特化)。
template <class T >
class C {}; //泛化版本接受T为任何类型
template <class T >
class C <T *>
{}; //这个特化版本仅接受T是一个原生指针的情况
{}; //这个特化版本仅接受T是一个原生指针的情况
下面是iterator_traits的代码,只简单取了一部分
template <class I >
struct iterator_traits {
typedef typename I:: value_type vaule_type ; //如果I有定义自己的value_type,就会被提取出来。
};
template <class I >
struct iterator_traits <T*>{
typedef I
vaule_type; //特化版本,适用于原生指针
vaule_type; //特化版本,适用于原生指针
};
template <class I >
struct iterator_traits <const T*>{
typedef T
vaule_type; //特化版本,适用于const指针,并且返回的是一个非const对象。
vaule_type; //特化版本,适用于const指针,并且返回的是一个非const对象。
};
STL中的iterator一共有五个属性:
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_categoty比较复杂,我们需要使用它来进行参数推导,以便提高效率,我们可以看到下面的声明,因为要进行编译时期的参数推导,我们需要为这些类型定义成类。而不能只是一个typedef。如下的继承关系,越往下iterator的功能越强大,比如random_access_iterator_tag就可以随机访问,拥有此能力的迭代器,我们必须使用他的高级功能以提高效率。
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 {};
如果我要实现一个iterator,如下:
template <class T >
struct myIter
{
typedef bidirectional_iterator_tag iterator_category ;
};
调用时只需:
template <class InputIterator , class Distance >
inline void advance(InputIterator &i , Distance n )
{
__advance( i, n,
iterator_traits <InputIterator >::iterator_category()); //创建临时对象,此对象是无用的,只是为了进行参数推导。
}