Traits编程技法:
1.要识别迭代器所指对象的类型,即所谓迭代器的value_type,可用模板参数推导机制推导出,但有其局限性,如无法推导出函数的返回值类型。
2.更好的方法是声明内嵌类型,如:
template<class T>
struct MyIter{
typedef T value_type;
T* ptr;
MyIter(T* p=0):prt(p){};
T& operator * () const {return *ptr;};
}
template<class I>
typename I::value_type//返回值类型,必须加typename,因为I::value_type是一个模板参数,在他被编译器具现化前编译器对他一无所知,typename告诉编译器这//是一个类型
func(I iter){
retrun *iter;
}
int main(){
MyIter<int> iter(new int(8));
func(iter);
retrun 0;
}
这里有一个隐晦的陷阱:并不是所有的迭代器都是class type的,如原始指针就不是。不是class type那么我们就不能使用声明内嵌类型了;
3.模板偏特化的意义:
a.偏特化的定义:针对(任何)模板参数更进一步的条件限制所设计出的一个特化版本,如template<class T> class AA{...};的一个特化版本template<class T> classAA<T*> {...};
b.萃取迭代器的特性,如下面这个类模板专门用来萃取迭代器的特性:
template<class I>
struct iterator_traits{
typedef typename I::value_type value_type;
};
所谓萃取是指如果I定义有自己的value_type,则这个类模板萃取出的value_type就是I的value_type。
c.iterator_traits通过偏特化萃取原始指针的类型:
template<class T>
struct iterator_traits<T*>{
typedef T value_type;
}