现在的位置: 首页 > 综合 > 正文

STL源码笔记之型别提取技法(1)

2014年07月09日 ⁄ 综合 ⁄ 共 1595字 ⁄ 字号 评论关闭

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           pointer
    typedef 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


抱歉!评论已关闭.