STL之traits編程技法

摘要

主要討論如何獲取迭代器相應型別。使用迭代器時,極可能用到其型別,若須要聲明某個迭代器所指對象的型別的變量,該如何解決。方法以下:編程

function template的參數推導機制

例如:函數

template<typename I, typename T>
void func_impl(I iter, T t)
{
    //T爲迭代器所指對象的型別
    T tmp;
    //.....
}

template<typename I>
inline
void func(I iter)
{   
    //func工做交給func_impl完成
    func_impl(iter, *iter);
}

int main()
{
    int i;
    func(&i);

    return 0;
}

func_impl()是一個 function template,一旦被調用,編譯器會自動進行template參數推導,從而導出型別T,無需本身指出型別,解決問題。迭代器相應型別不僅是迭代器所指對象的型別一種而已,最經常使用的相應型別有五種,但並不是任何狀況均可利用上述template參數推導機制來取得。這就須要其餘方法。設計

Traits編程技法

迭代器所指對象的型別,成爲該迭代器的value type,上述模板參數推導並不是全面可用,在須要value type做爲函數返回值時,就不能解決了。template參數推導的只是參數而已。所以,聲明內嵌型別就出現了。指針

例如:code

template<typename T>
struct MyIter
{
    typedef T value_type;   //內嵌型別聲明
    T* ptr;
    MyIter(T* p = nullptr):ptr(p) { }
    T& operator*() const { return *ptr;}
    //...
};

template<typename I>
typename I::value_type  //函數func()的返回類型,爲I類型迭代器中的value_type
func(I ite)
{
    return *ite;
}
int main()
{
    MyIter<int> ite(new int(8));
    cout<<func(ite);    //輸出8
    return 0;
}

func()函數的返回值必須加上關鍵字typename,用來告訴編譯器這時一個模板類型。但並非全部迭代器都爲class type,原生指針就不是,它就不能定義內嵌型別。這時模板偏特化(template partial specialization)就能解決這個問題。對象

偏特化的意義

若是class template擁有一個以上的template參數,咱們能夠針對其中某個(或數個,但並不是所有)template參數進行特化工做。也就是將泛化版本中的某些template參數給予明確的指定。ci

如:編譯器

template<typename U, typename V, typename T>
class C { }

偏特化不是template參數U、V或T指定某個參數值,而是針對(任何)template參數更進一步的條件限制所設計出來的一個特化版本。看這個例子:it

//泛化版本
template<typename T>
class C { }
//偏特化版本
template<typename T>
class C<T*> { } //解決原生指針的問題

如此便能解決前面的內嵌型別的問題。下面這個class template專門用來萃取迭代器的特性之一 :value_typeio

template<typename I>
struct Iterator_traits  //traits指的是特性
{
    typedef typename I::value_type value_type;
}
相關文章
相關標籤/搜索