Template所代表的泛型編程是C++語言中的重要的組成部分,我將通過幾篇blog對這半年以來的學習做一個系統的總結,本文是基礎篇的第三部分。
Template 基礎篇-參數魔法默認實參模板的模板參數非類型參數
除了使用類型作為模板的參數之外,模板參數有更多的用法,以下做個詳細介紹。
我們可以通過給模板指定默認實參,為用戶推薦合適的默認設定,讓用戶在只指定部分(或完全不指定)實參的情況下使用模板。
注意:模板的默認實參與函數的默認實參一樣,必須從右向左定義。
在C++98中,只能為類模板指定默認實參。
template<typename T = int, typename U> //error, 必須從右向左struct Wrapper1 { T t;};template<typename T, typename U = int> //okstruct Wrapper2 { T t;};Wrapper2<double> w;template<typename T = int>struct Wrapper3 { T t;};Wrapper3<> w; //w的類型為Wrapper<int>,注意空的<>必須寫上在C++11中,還可以為函數模板指定默認實參
template<typename T, typename F = std::less<T>> //指定F的默認值是std::less<T>int compare(const T& left, const T& right, F f = F()) { //注意這里,std::less是一個functor if (f(left, right)) { return -1; } if (f(right, left)) { return 1; } return 0;}compare(1, 2); //未指定第三個參數,使用默認值std::less<int>除了內置類型(int float bool等)和自定義類型(class struct)可以作為模板實參之外,C++還允許使用一個模板作為另外一個模板的實參,這使得模板的用戶可以對模板的行為進行深度的定制。例如:指定模板存儲數據使用另外一種STL容器。
聲明模板的模板參數時,必須使用template和class關鍵字,必須使用另外一個模板的完整聲明。
template<typename T, template<typename ELEM> typename CONT> //error,必須使用class關鍵字class ContainerWrapper {public: CONT<T> elems;};template<typename T, template<typename ELEM> class CONT> //okclass ContainerWrapper {public: CONT<T> elems;};ContainerWrapper<int, std::deque> cw; //error,std::deque不匹配//std::deque中除了ELEM之外還有一個有默認值的Alloc參數template<typename T, template<typename ELEM, typename ALLOC = std::allocator<ELEM>> class CONT = std::deque> //兼容STL容器的模板實參,默認為deque,注意template和class兩個關鍵詞class ContainerWrapper {public: CONT<T> elems;};ContainerWrapper<int> cw_default; //使用deque存儲ContainerWrapper<double, std::vector> cw_customized; //指定底層存儲類型為vectorC++模板還支持非類型參數,我們可以在模板定義中使用一個具體類型來指定它們。一個非類型參數可以是一個整形,或者是指針或左值引用。
template<unsigned N, unsigned M> //使用unsigned標記非類型參數int compare(const char (&left) [N], const char (&right) [M]) { return compare(left, right);}compare("hi", "hello"); //推斷出N=3,M=6template<typename T, int N>class WrapperWithNum {public: T t;};WrapperWithNum<int, 1> wwn1;WrapperWithNum<int, 2> wwn2; //注意:雖然兩個模板實例的T都是int,但是因為N不同,所以這是兩個類型注意:對于含有非類型參數的函數模板,整形推斷的結果必須是一個常量表達式,指針和引用推斷的結果必須指向具有靜態生存周期的對象(static或者全局)或者是nullptr或0。
新聞熱點
疑難解答
圖片精選