本文主要是介绍STL源码笔记之型别提取技法(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
STL源码利用Traits类来萃取,模板参数一些型别,我觉得蛮不错,做个笔记。
1.利用function template的参数推导机制
template<class I,class T>
Void func_impl(I iter,T t)
{T tmp;//
};
template<class I>
Void func_impl(I iter)
{func_impl(iter,*iter);
}
int main()
{int I;func(&i);//编译器会自动进行template参数推导
}
迭代器所指对象的型别,称为迭代器的value_type。上面技巧可以用于value_type,但是不是全面可用。万一value_type必须用于函数的传回值,毕竟template的参数推导机制导出的只是输入参数,无法推导函数的返回值型别。
2.内嵌型别
内嵌型别似乎能解决这个问题:
template<class T>
struct MyIter{typedef T value_type;T* ptr;
};
template<class I>
typename I::value_type
func(I ite){return*ite;
}
MyIter<int>ite(new int(4));
Cout<<func(ite);
Func()的返回类型必须加上关键字typename,因为T是一个template参数,它在编译之前,编译器对T一无所知,并不知道MyIter<T>::value_type是一个型别还是一个function还是一个data member。关键字typename告诉编译器这是一个型别。
3.偏特化
这种方案看起来是可行,但是有个陷阱,并不是所有的迭代器都是class Type,原生指针就不是。如果不是class Type,就无法定义内部型别,但是我们可以针对这种特殊情况定义特化版本,也就是将泛化版本中某些参数template参数明确固定。我们针对template参数更进一步的条件限制所设计出来的特化版本:
template<class I>
calss C{…….}; //允许I为任何型别
template<class I>
calss C<T*>{…….}; //这个特化版本仅适用于“T原生指针”的情况。
4.STL中的Traits技术
template<class T>
struct iterator_traits{typedef typename I::value_type value_type;typedef typename I::iterator_category iterator_category;typedef typename I::difference_type difference_type;typedef typename I::pointer pointertypedef typename I::reference reference
};
//两个特化版本
template<class T>
struct iterator_traits<const T*>{typedef T value_type;
…
};template<class T>
struct iterator_traits<const T*>{typedef T value_type;
…
};
//应用
template<class T>
typename iterator_traits<I>::value_type
func(I ite)
{return*ite;
}
注:若要使用这个“特性萃取机”,每个迭代器必须遵守约定,自行定义内嵌型别定义。
注:我可以学到的两点:型别提取技术,template的特化
5.迭代器(iterator)中的型别
迭代器中包含有五种型别:value_type、difference_type、reference_type、pointer_type和iterator_category
这篇关于STL源码笔记之型别提取技法(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!