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