国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C++ 模板基礎(chǔ)談 - C/C++ / C++ 語言
打算給公司的同事上課,以便推廣 C++ 模板,寫了以下教程。希望能看到各種意見,以便完善它。

C++ 模板基礎(chǔ)談

1. 什么是模板
模板定義:模板就是實(shí)現(xiàn)代碼重用機(jī)制的一種工具,它可以實(shí)現(xiàn)類型參數(shù)化,即把類型定義為參數(shù),從而實(shí)現(xiàn)了真正的代碼可重用性。
我們知道,C++ 是一種“強(qiáng)類型”的語言,也就是說一個(gè)變量,編譯器必須確切的知道它的類型,而模板就是構(gòu)建在這個(gè)強(qiáng)類型語言基礎(chǔ)上的泛型系統(tǒng)。

2. 模板的語法
模板函數(shù)
template< typename {類型參數(shù)名稱}, [ int {Name}=...][, ...] >
{函數(shù)定義}

模板類
template< typename ... , [ int {Name}=...] >
class ...

模板的參數(shù)可以是類型,或者是一個(gè) int 型的值(或者可以轉(zhuǎn)換為int 型的,比如 bool)。

3. 模板的使用
顯式類型參數(shù):對于模板函數(shù),在函數(shù)名后添加 < {類型參數(shù)表} >。對于模板類,在類后添加 < {類型參數(shù)表} >
隱式類型參數(shù):對于模板函數(shù),如果類型參數(shù)可以推導(dǎo),那么可以省略類型參數(shù)表
舉個(gè)例子:
template< typename T >
T max( T a, T b )
{
  return a < b ? b : a;
}

這個(gè) max 函數(shù)就是一個(gè)模板函數(shù),它可以傳入一個(gè) “類型”的參數(shù),以便實(shí)現(xiàn)任意類型求最大值的效果。假設(shè)我們這樣使用它:
int x=5, y=10;
int z=max<int>( x, y );
這時(shí)候發(fā)生了什么呢?我們傳入的“類型參數(shù)”是int,因此編譯器在編譯這段代碼時(shí)會(huì)使用 int 來構(gòu)造一個(gè)新函數(shù):
int max( int a, int b )
{
  return a < b ? b : a;
}
后面的事就和編譯普通的函數(shù)一樣了,C++編譯器繼續(xù)使用強(qiáng)類型系統(tǒng)編譯這個(gè)函數(shù),由強(qiáng)類型系統(tǒng)來檢查這個(gè)函數(shù)是否正確。
這個(gè)過程叫做模板的“特化”,它發(fā)生在編譯期,當(dāng)編譯器發(fā)現(xiàn)模板函數(shù)、模板類被使用(注意,不是定義)的時(shí)候進(jìn)行的。這個(gè)系統(tǒng)實(shí)際上比較像宏,但是比宏更為智能。
很明顯,編譯器必須知道模板如何特化這個(gè)函數(shù),因此模板函數(shù)的實(shí)現(xiàn),必須在“使用點(diǎn)”之前,因此模板庫只能通過頭文件庫的形式來提供。

4. 模板的類型推導(dǎo)
對于函數(shù),編譯器是知道傳入?yún)?shù)的類型的,比如上面的max,max< ? >( x, y ),由于第一個(gè)參數(shù) x 是 int 類型的,那么 ? 這里需要填寫什么呢?
我們可以很明顯的推斷出應(yīng)該是 "int",否則,后面的強(qiáng)類型系統(tǒng)將無法編譯這個(gè)函數(shù)。編譯器同樣知道 x 的類型,因此它也能推導(dǎo)出“類型參數(shù)”,這時(shí)候我們調(diào)用時(shí)就可省略模板參數(shù)了。
這個(gè)推導(dǎo)是按順序來的,因此如果上面的 y 是其他類型,? 仍然會(huì)被推導(dǎo)為 int,如果y無法隱性轉(zhuǎn)換為int,強(qiáng)類型編譯時(shí)就會(huì)報(bào)錯(cuò)。

5. 類型推導(dǎo)的隱式類型轉(zhuǎn)換
在決定模板參數(shù)類型前,編譯器執(zhí)行下列隱式類型轉(zhuǎn)換:

  左值變換
  修飾字轉(zhuǎn)換
  派生類到基類的轉(zhuǎn)換

  見《C++ Primer》([注2],P500)對此主題的完備討論。

簡而言之,編譯器削弱了某些類型屬性,例如我們例子中的引用類型的左值屬性。舉例來說,編譯器用值類型實(shí)例化函數(shù)模板,而不是用相應(yīng)的引用類型。

同樣地,它用指針類型實(shí)例化函數(shù)模板,而不是相應(yīng)的數(shù)組類型。

它去除const修飾,絕不會(huì)用const類型實(shí)例化函數(shù)模板,總是用相應(yīng)的非 const類型,不過對于指針來說,指針和 const 指針是不同的類型。

底線是:自動(dòng)模板參數(shù)推導(dǎo)包含類型轉(zhuǎn)換,并且在編譯器自動(dòng)決定模板參數(shù)時(shí)某些類型屬性將丟失。這些類型屬性可以在使用顯式函數(shù)模板參數(shù)申明時(shí)得以保留。

6. 模板的偏特化
如果我們打算給模板函數(shù)(類)的某個(gè)特定類型寫一個(gè)函數(shù),就需要用到模板的偏特化,比如我們打算用 long 類型調(diào)用 max 的時(shí)候,返回小的值(原諒我舉了不恰當(dāng)?shù)睦樱?br>template<> // 這代表了下面是一個(gè)模板函數(shù)
long max<long>( long a, long b ) // 對于 vc 來說,這里的 <long> 是可以省略的
{
  return a > b ? b : a;
}
實(shí)際上,所謂偏特化,就是代替編譯器完成了對指定類型的特化工作,現(xiàn)代的模板庫中,大量的使用了這個(gè)技巧。

7. 仿函數(shù)
仿函數(shù)這個(gè)詞經(jīng)常會(huì)出現(xiàn)在模板庫里(比如 STL),那么什么是仿函數(shù)呢?
顧名思義:仿函數(shù)就是能像函數(shù)一樣工作的東西,請?jiān)徫矣脰|西這樣一個(gè)代詞,下面我會(huì)慢慢解釋。
void dosome( int i )
這個(gè) dosome 是一個(gè)函數(shù),我們可以這樣來使用它: dosome(5);
那么,有什么東西可以像這樣工作么?
答案1:重載了 () 操作符的對象,比如:
  struct DoSome
  {
  void operator()( int i );
  }
  DoSome dosome;
這里類(對 C++ 來說,struct 和類是相同的) 重載了 () 操作符,因此它的實(shí)例 dosome 可以這樣用 dosome(5); 和上面的函數(shù)調(diào)用一模一樣,不是么?所以 dosome 就是一個(gè)仿函數(shù)了。

實(shí)際上還有答案2:
  函數(shù)指針指向的對象。
  typedef void( *DoSomePtr )( int );
  typedef void( DoSome )( int );
  DoSomePtr *ptr=&func;
  DoSome& dosome=*ptr;
   
  dosome(5); // 這里又和函數(shù)調(diào)用一模一樣了。
當(dāng)然,答案3 成員函數(shù)指針指向的成員函數(shù)就是意料之中的答案了。

8. 仿函數(shù)的用處
不管是對象還是函數(shù)指針等等,它們都是可以被作為參數(shù)傳遞,或者被作為變量保存的。因此我們就可以把一個(gè)仿函數(shù)傳遞給一個(gè)函數(shù),由這個(gè)函數(shù)根據(jù)需要來調(diào)用這個(gè)仿函數(shù)(有點(diǎn)類似回調(diào))。

STL 模板庫中,大量使用了這種技巧,來實(shí)現(xiàn)庫的“靈活”。
比如:
for_each, 它的源代碼大致如下:
template< typename Iterator, typename Functor >
void for_each( Iterator begin, Iterator end, Fucntor func )
{
  for( ; begin!=end; begin++ )
  func( *begin );
}

這個(gè) for 循環(huán)遍歷了容器中的每一個(gè)元素,對每個(gè)元素調(diào)用了仿函數(shù) func,這樣就實(shí)現(xiàn)了 對“每個(gè)元素做同樣的事”這樣一種編程的思想。

特別的,如果仿函數(shù)是一個(gè)對象,這個(gè)對象是可以有成員變量的,這就讓 仿函數(shù)有了“狀態(tài)”,從而實(shí)現(xiàn)了更高的靈活性。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C 模板
<轉(zhuǎn)載>獨(dú)一無二的C++模板
C加加模板之類模板的特化
《Effective C 》讀書摘要
C ++template模板 學(xué)習(xí)筆記
構(gòu)建吞吐量系列之模板元編程基礎(chǔ)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服