应用需求:当我们使用迭代器的时候,可能在函数中返回迭代器,所以要求能够在函数声明的时候就要指明函数的返回类型。这里就可能是迭代器的类型
因此我们需要方法获得迭代器的类型。
C++缺陷:由于C++不支持typeof () 不能在运行时候得到迭代器的型别(迭代器的型别只有就是容器中元素的类型) ,而RTTI(动态运行时)中的TypeID() 只能获得型别的名称
,不能拿来做变量声明之用。
解决方案1:利用function template 的参数推导机制。
如下:
template <class I, class T>
void func_helper(I iter, T t){
T tmp; // 这里就是推导出的迭代器所指之物的类型
... //这里做func原本该做的工作
}
template <class I>
void func(I iter){
func_helper(iter, *iter); //*iter作为附加参数
}
void main(){
int i;
func(&i);
}
缺点: 第一,迭代器的型别不只是“迭代器所指对象的型别”,第二,推导出型别不能作为返回值类型
解决方案2: traits技法-------------把迭代器所指对象(不仅是迭代器所指对象)声明为内部类型。
如下:
template<class T>
struct MyIter {
typedef T value_type;// 声明为内嵌型别
T* ptr;
MyIter (T* p=0):ptr(p){}
T& operator*() const { return *ptr;}
};
template<class I>
typename I::value_type //这是函数返回类型(即迭代器所指对象类型)
fun(I ite)
{return *ite; }
MyIter<int> ite(new int(8));
cout<< func(ite);
缺点:并不是所有的迭代器都是class type (类,或者结构体 ,类和结构体内部都可以声明内嵌类型),比如说 int* 类型就不可以定义内部类型。但要适应这种情况 是必须的
改进:偏特化,可以弥补traits技法的不足。
普通的内嵌类型如下:
template<class I>
struct iterator_traits{
typedef typename I::value_typevalue_type;
};
对原生指针的偏特化如下:
template<class I>
struct iterator_traits<T*>{
typedef typename I::value_typevalue_type;
};
traits 扮演 “特性萃取机”角色,萃取出迭代器相应的型别