<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
C++template的最初發展動機很直接:讓我們得以建立“型別安全”的容器如vector,list和map。然而當愈多人用上templates時,他們發現template有能力完成愈多可能的變化。容器當然很好,但泛型程式設計(generic programming)——寫出的程式碼和其所處理的物件型別彼此獨立——更好。STL演演算法如for_each,find和merge就是這一類程式設計的結果。最終人們發現,C++template機制自身是一部完整的圖靈機:它可以用來計算任何可計算的值。於是匯出了模板超程式設計(template mataprogramming),創造出“在C++編譯器內執行並於編譯完成時停止執行”的程式。
物件導向程式設計(OOP)和泛型程式設計都可以處理編寫程式時不知道型別的情況;二者的不同之處在於:OOP能處理型別在程式執行之前都未知的情況;而在泛型程式設計中,在編譯時就能獲知型別了
我們所常用的STL標準庫中,每一個容器都提供了單一的,泛型的定義,例如我們所常用的vector,我們可以定義很多型別的vector
vector<int> vi; // vi是裝載int型別的vector容器的範例 vector<string> vs; // vs是裝載string型別的vector容器的範例 vector<double> vd; // vd是裝載double型別的vector容器的範例
模板是泛型程式設計的基礎,一個模板就是一個建立類或者函數的藍圖或者公式
// 簡單的比較函數模板 template<typename T> int cmp(const T& v1,const T& v2) { if(v1<v2) return -1; else if(v1>v2) return 1; else return 0; }
函數定義以關鍵字template開始,後跟一個模板參數列,這是一個逗號分隔的一個或多個模板引數的列表,用尖括號包圍起來
**注:**在模板定義中,模板參數列不能為空
模板參數列表示在類或函數定義中用到的型別或者值。當我們使用模板的時候,我們可以(顯式或隱式地)指定模板實參,將其繫結到模板引數上
簡單瞭解模板的範例化過程
眾所周知,當你覺得模板程式設計十分智慧的時候,一定是有東西在為你負重前行,C++提供了模板與泛型程式設計的這個能力,這便意味著有一個東西在為你動態地實現模板的功能,而這一定是比C++這個高階語言層面更為底層的東西,而我們所瞭解的知識中,比C++高階語言較為底層的東西,除了作業系統,便是編譯器了。
當我們呼叫一個函數模板的時候,編譯器(通常)用函數實參來為我們推斷模板實參。簡單來講,便是我們在呼叫函數模板的時候,編譯器通過使用實參的型別來確定繫結到模板引數T的型別
cout<<cmp(1,0)<<endl; // T為int
在上訴程式碼中,函數cmp的實參型別是int,編譯器便會推斷出模板實參為int,並將它繫結到模板引數T上
簡單來說,編譯器用推斷出的模板引數來為我們範例化一個特定版本的函數
當編譯器遇到一個模板定義的時候,它並不會生成程式碼。只有我們範例化出模板的一個特定的版本時,編譯器才會生成其對應的程式碼。當我們使用(而不是定義)模板時,編譯器才會生成程式碼。這個特性影響我們如何組織程式碼以及錯誤何時才可以被檢測到
通常來說,我們將類定義和函數說明放在標頭檔案中,而普通函數和類的成員函數的定義放在原始檔中
模板則不盡相同:為了生成一個範例化的版本,編譯器需要掌握函數模板或類別範本成員函數的定義
總結:與非模板程式碼不同,模板的標頭檔案通常既包括宣告也包括定義,即函數模板和類別範本成員函數的定義通常放在標頭檔案中
大多數編譯錯誤出現的時機
**注意事項:**保證傳遞給模板的實參支援模板所要求的操作,以及這些操作在模板中能正確的工作,是呼叫者的責任
類別範本是用來生成類的藍圖的。與函數模板不同之處是,編譯器不能為類別範本推斷模板引數型別。 所以我們必須在模板名後的尖括號中提供額外的資訊——用來替代模板引數的模板實參列表
vector<int> vi; deque<double> dd; pair<string,int> key_val;
定義類別範本
template<typename T> class T_vector { public: typedef T value_type; // 建構函式 T_vector() =default; T_vectot(std::initializer_list<T> il); // 容器的元素數目 size_type size() const { return data->size(); } bool empty() const { return data->empty(); } // 新增元素 void push_back(const T& val) { data->push_back(val); } void push_back(T &&val) { data->push_back(std::move(val)); } private: std::shared_ptr<std::vector<T> > data; // 若data[i]無效,則丟擲msg void check(size_type i,const std::string &msg) const; }
類似函數模板,類別範本以關鍵字template開始,後跟模板參數列。在類別範本(及其成員)的定義中,我們將模板引數當作替身,代替使用模板時使用者需要提供的型別或值
**注:**一個類別範本的每一個範例都形成一個獨立的類,而類別範本的每個範例都有其自己版本的成員函數
所以,我們可能會出現一個單一模板並不能滿足所有型別的需求,而模板特例化就出現了
類別範本成員函數的範例化
預設的情況下,一個類別範本的成員函數只有在程式用到它的時候才會範例化
// 範例化T_vector和接受initializer_list<int>的建構函式 T_vector<int> T_vi = { 0,1,2,3,4,5 };
如果一個成員函數沒有被使用,則它將不會被範例化
當我們編寫單一的模板時,使其對任何可能的模板實參都是最合適的,都能範例化,但者往往都是過於理想化的情況。在某些特殊的情況下,通用的模板的定義可能對特定的型別是不合適的,通用定義的模板可能會出現編譯失敗或者做得不夠完善的情況。
故,當我們不能(或者不希望)使用模板版本的時候,可以定義類或函數模板的一個特例化版本
定義函數模板特例化
// 原先cmp函數的特殊版本,用來處理特殊的字元陣列的指標template<>int cmp(const char* const& p1,const char* const& p2) { return strcmp(p1,p2);}// 原先cmp函數的特殊版本,用來處理特殊的字元陣列的指標 template<> int cmp(const char* const& p1,const char* const& p2) { return strcmp(p1,p2); }
函數過載與模板特例化的區別
當定義函數模板的特例化版本時,我們本質上接管了編譯器的工作。即,我們為原先的模板的其中一個特殊的範例提供了定義。簡而言之,特例化的本質是範例化一個模板,而非過載它,因此特例化並不影響函數匹配
注意事項:
類別範本部分特例化
與函數模板不同的是,類別範本的特例化不必為所有模板引數提供實參。一個類別範本的部分特例化本身是一個模板,使用它時使用者還必須為那些在特例化版本中指定的模板引數提供實參
注:我們只能部分特例化類別範本,而不能部分特例化函數模板
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45