《C++ Template. The Complete Guide》筆記之四 Tricky Basics

這裏實際要說到的是一些散亂的比較tricky的概念。不想一一列舉了,但是有2個點想拿出來說一說。

第一個就是typename,這個關鍵字用來告訴編譯器,後面緊跟的東西是一個類型而不是其他什麼東西。假定你有一個Map的類,需要有2個模板參數Key和Value。

有了這個類之後,我們要實現這裏的getPair方法。我們按部就班地寫出這個函數的實現:

template<class K, class V> Map<K,V>::MapPair Map<K,V>::getPair() 但是編譯的時候,

GCC的編譯器(我用的是和CodeBlock綁定的gcc 3.4.5,可能比較老了)告訴我們"error: expected constructor, destructor, or type conversion before "Map"|||=== Build finished: 1 errors, 0 warnings ===|"

VS2005的編譯器告訴我們"error C2143: syntax error : missing ';' before 'Map<K,V>::getPair'"和“error C4430: missing type specifier - int assumed. Note: C++ does not support default-int”

這裏可以看到VS的編譯器還是比較靠譜的,能把你往這個typename關鍵字上指引,但是GCC的有點詭異。這裏的解決方案就是把這個函數寫成:

template<class K, class V> typename Map<K,V>::MapPair Map<K,V>::getPair()

這裏的typename用來表明這裏的::MapPair表示的是MapPair是一個類型,而不是Map<K,V>中的一個變量。這樣變量其實我們在STL中經常看見。只是沒有特別關注罷了,比如說下面的例子:

上面這個就是在STL istream中的一段定義,這裏沒有typename可能不能通過編譯。更甚者,形如typename T::SubType* ptr;這樣的語句如果沒有加上typename通過了編譯,被解析成爲T中的變量SubType乘以ptr纔是非常恐怖的。

 

還有一個原來以爲沒有問題的問題。就是文中提到的this->的問題

來看這樣一個例子:

這裏的特點是派生類的foo函數中調用幹了exit()函數。問題是這裏有2個函數,一個是全局的exit函數,一個事父類Base中的成員函數,現在這樣的調用究竟是調用哪個函數呢?我們在GCC和VS的編譯器中都做了嘗試。

VS的編譯器似乎很進步,一直爲了這些模板問題在做改進。這裏的輸出是“base exit”。如我們所願。但是在GCC(gcc 3.4.5)裏面輸出了"global exit"。Again,可以想到的一個潛在的問題就是如果你寫一個在Windows Mobile和Symbian上公用的模塊,即使在Windows Mobile上可以運行,但是在Symbian上行爲表現可能就不一樣了。。

所以這裏老老實實的用this->exit();或者Base::exit();纔是一個穩妥的辦法。

這章裏面涉及到的還不止這些內容。比如.template的用法其實也有提及。但是如果是淺嘗輒止就沒有什麼特別的意思了。留待下次在具體分析。

 

 

 

發佈了70 篇原創文章 · 獲贊 9 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章