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
}

 

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