C++ 中的类型萃取理论

最近在看fastertransfomer源码,其中里面涉及到不少trait的技巧,记得之前在看stl的时候有涉及过,简单对该方法进行简单记录。

在STL中,算法和容器是隔离开的,比如排序算法适用于vector,list,queue,而算法和容器的联系的桥梁就是迭代器,迭代器简单说

就是一个包装好的指针,算法可以利用指针来实现,现在有一问题,如果该算法函数要返回该指针指向的类型,那么该模板函数该怎么写:

template<class T>
(?) double(T iterator)
{
    do something;
    return 2*(*iterator)
}

为了解决这个问题,直观的想法是迭代器这个类中有其对象所指的类型,如下:

template <class T>
class MyIter {
    typedef T value_type; // A nested type declaration, important!!!
    T* ptr;
    MyIter(T* p = 0) : ptr(p) {}
    T& operator*() const { return *ptr; }
};

那么?则可以用typename T::value_type来代替,其实这里基本解决了问题,为了进一步适用广泛,比如内置类型指针就没办法,为此加一个中间层:iterator_trait

//普通迭代器
template <class I>
struct iterator_traits 
{
    Typedef I::value_type value_type;
}
//内置类型,比如int
template <class I>
struct itertor_traits<T*> 
{
    typedef T value_type;
};
//最终的函数
template <class I>
typename iterator_traits<I>::value_type func(I ite) 
{
    return *ite;
}

iterator_trait就是利用偏特化实现的一萃取操作,嗯,整个流程看起来的核心思想就是通过trait拿出了指针的指向类型,一定程度上封装了不同类型指针的获取指向类型的细节,用户可以不用关心模板传进来的指针类型,通过模板配合trait方法设计算法的人员可以更加省心省力。

其他利用场景:

一般来说,如果我们涉及到一个类型决定一批类型的时候,那么就可以设置一个模板类trait,把这些受影响的类型都放在trait中,

 

//定义一个模板(空壳子)
template <class T>
class Trait;
//实例化1
template <>
class Trait<class1>
{
    typedef class1 datatype;
    typedef float* ptrtype;
}
//实例化2
tempalte <>
class Trait<class2>
{
    typedef class2 datatype;
    typedef int* ptrtype;
}
//偏特化,下面这个就可以用在内置类型里
template <class T>
class Trait<T*>
{
    //do something
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章