《STL源码剖析》学习-- 1.9-- 可能令你困惑的C++语法1
最近在看侯捷的《STL源碼剖析》,雖然感覺自己c++看得比較深一點,還是感覺還多東西不是那么明白,這里將一些細小的東西或者概念記錄一下。
有些東西是根據《C++編程思想》理解的,記錄一下加深印象。
STL沒有太多的OO(object oriented),基本思想是GP(Generic Programming)。模板是泛型編程最基礎的東西。
這里主要針對1.9節 可能令你困惑的C++語法 所列出來的組態進行講解,因為書上基本沒什么講解。
1、模板 template
1.1 默認模板參數
很簡單的類似于函數的默認參數,只要在后面加等于具體的類名即可以了。
如:template<class T, class U = char> void f() {?T a;?U b; };
1.2 typename:
?如果在用模板定義的函數內如果不用typename標出類名,則只能把標示符當做類的靜態成員,可以訪問,但卻不能新建類型,
如下代碼:id為嵌套的類型。此時typename的作用是通知編譯器,被限定的標示符為一個類型。
template<typename T> class M{//typename T::id i;T::id i; public:void f(){ i.g();} };class X{ public:class id{public:void g(){cout <<"x" <<endl;};}; };當沒有typename時,無法定義i,但是我用函數時確實可以的,如下:
template<typename T> void func(){T::id i;i.g(); } int main(){func<X>();system("pause");}可能是不同編譯器的原因,為了程序穩定性,模板編程過程中還是最好用typename。
1.3 模板類型推斷
在實例化類模板時,總是需要使用尖括號并且提供所有的非默認模板參數;然而在實例化函數模板時,經常可以省略模板參數。
如:
template< typename T> const T& min(const T& a, const T& b){return (a<b)? a:b;}可以通過加尖括號來調用,也可以不,讓編譯器從函數的參數中推斷出模板的類型,這就是類型推斷。
如調用min可以如下:
int i,j;int z= min(i,j); 但此時i,j類型必須完全一致,如果不一致,即使可以進行類型轉換(如int 和 float),但是編譯器依然會報錯,此時必須明確指出模板類型。1.4 偏特化
一般的往往將偏特化理解為給定模板中的部分模板參數以具體的類,余下的泛化。其實不然,在本書3.4節traits編程技法一節,提到,“所謂partial specialization 的意思是提供另一份template的定義式,而其本身仍為templatized。”,“針對(任何)template參數更進一步的條件限制所設計出來的一個特化版本”。
全特化就是所有的模板都為具體的類。
T* 特化允許用指針類型匹配的模式(也只能匹配指針類型),const T* 特化允許使用指向const的指針 類型匹配(也只能匹配指向const的指針)。
注意,類模板可以偏特化,而函數模板不可以偏特化,即函數名后不可以加<>,但是可以通過重載達到類似偏特化的效果。
當有好多個版本的函數符合模板函數規則時,為了避免二義性,編譯器總是選擇特化程度最高的的模板。
如 template<class T,class U> void f() { T a; U b; };
某個特化版本為 template<> void f<int,char>() {?int a;?char b; };
某個偏特化版本為 template<class U> void f<int,U>() {?int a;?U b; };
1.5模板和友元(主要是限定友元)bound friend templates
class template 的某個具體實現與friend function template的某個具體實現有一對一的關系。
友元函數模板必須提前聲明,本書中寫到GCC中不需要前置聲明。
如下,f()為Friendly類的友元函數,都為模板。此例中兩者都是int的示例,注意Friendly中的f的聲明里尖括號(或者<T>,不寫也很容易推斷),訴編譯器f是一個模板,而不是普通函數,否則編譯器就會找普通函數而找不到。
template<class T> class Friendly; template<class T> void f(const Friendly<T>&);template<class T> class Friendly{T t; public:Friendly(const T& theT):t(theT){}friend void f<>(const Friendly<T>&);void g(){f(*this);} };template<class T> void f(const Friendly<T>& fo){cout << fo.t << endl; } void h(){f(Friendly<int>(1)); }int main(){h();Friendly<int>(2).g(); } 總結
以上是生活随笔為你收集整理的《STL源码剖析》学习-- 1.9-- 可能令你困惑的C++语法1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《STL源码剖析》学习--6章--_ro
- 下一篇: 《STL源码剖析》学习-- 1.9--