欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言的模板與泛型編程你了解嗎

 更新時(shí)間:2022年03月31日 13:07:32   作者:日天少年wzh  
這篇文章主要為大家詳細(xì)介紹了C語言的模板與泛型編程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

模板與泛型編程淺談

摘要(Effective C++):

? C++template的最初發(fā)展動機(jī)很直接:讓我們得以建立“類型安全”的容器如vector,list和map。然而當(dāng)愈多人用上templates時(shí),他們發(fā)現(xiàn)template有能力完成愈多可能的變化。容器當(dāng)然很好,但泛型編程(generic programming)——寫出的代碼和其所處理的對象類型彼此獨(dú)立——更好。STL算法如for_each,find和merge就是這一類編程的結(jié)果。最終人們發(fā)現(xiàn),C++template機(jī)制自身是一部完整的圖靈機(jī):它可以用來計(jì)算任何可計(jì)算的值。于是導(dǎo)出了模板元編程(template mataprogramming),創(chuàng)造出“在C++編譯器內(nèi)執(zhí)行并于編譯完成時(shí)停止執(zhí)行”的程序。

模板與泛型編程簡單介紹

? 面向?qū)ο缶幊蹋∣OP)和泛型編程都可以處理編寫程序時(shí)不知道類型的情況;二者的不同之處在于:OOP能處理類型在程序運(yùn)行之前都未知的情況;而在泛型編程中,在編譯時(shí)就能獲知類型了

? 我們所常用的STL標(biāo)準(zhǔn)庫中,每一個(gè)容器都提供了單一的,泛型的定義,例如我們所常用的vector,我們可以定義很多類型的vector

vector<int> vi; // vi是裝載int類型的vector容器的實(shí)例
vector<string> vs; // vs是裝載string類型的vector容器的實(shí)例
vector<double> vd; // vd是裝載double類型的vector容器的實(shí)例

模板是泛型編程的基礎(chǔ),一個(gè)模板就是一個(gè)創(chuàng)建類或者函數(shù)的藍(lán)圖或者公式

函數(shù)模板

// 簡單的比較函數(shù)模板
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;
}

函數(shù)定義以關(guān)鍵字template開始,后跟一個(gè)模板參數(shù)列表,這是一個(gè)逗號分隔的一個(gè)或多個(gè)模板參數(shù)的列表,用尖括號包圍起來

**注:**在模板定義中,模板參數(shù)列表不能為空

模板參數(shù)列表表示在類或函數(shù)定義中用到的類型或者值。當(dāng)我們使用模板的時(shí)候,我們可以(顯式或隱式地)指定模板實(shí)參,將其綁定到模板參數(shù)上

簡單了解模板的實(shí)例化過程

? 眾所周知,當(dāng)你覺得模板編程十分智能的時(shí)候,一定是有東西在為你負(fù)重前行,C++提供了模板與泛型編程的這個(gè)能力,這便意味著有一個(gè)東西在為你動態(tài)地實(shí)現(xiàn)模板的功能,而這一定是比C++這個(gè)高級語言層面更為底層的東西,而我們所了解的知識中,比C++高級語言較為底層的東西,除了操作系統(tǒng),便是編譯器了。

? 當(dāng)我們調(diào)用一個(gè)函數(shù)模板的時(shí)候,編譯器(通常)用函數(shù)實(shí)參來為我們推斷模板實(shí)參。簡單來講,便是我們在調(diào)用函數(shù)模板的時(shí)候,編譯器通過使用實(shí)參的類型來確定綁定到模板參數(shù)T的類型

cout<<cmp(1,0)<<endl; // T為int

在上訴代碼中,函數(shù)cmp的實(shí)參類型是int,編譯器便會推斷出模板實(shí)參為int,并將它綁定到模板參數(shù)T上

簡單來說,編譯器用推斷出的模板參數(shù)來為我們實(shí)例化一個(gè)特定版本的函數(shù)

模板編譯

當(dāng)編譯器遇到一個(gè)模板定義的時(shí)候,它并不會生成代碼。只有我們實(shí)例化出模板的一個(gè)特定的版本時(shí),編譯器才會生成其對應(yīng)的代碼。當(dāng)我們使用(而不是定義)模板時(shí),編譯器才會生成代碼。這個(gè)特性影響我們?nèi)绾谓M織代碼以及錯(cuò)誤何時(shí)才可以被檢測到

通常來說,我們將類定義和函數(shù)說明放在頭文件中,而普通函數(shù)和類的成員函數(shù)的定義放在源文件中

模板則不盡相同:為了生成一個(gè)實(shí)例化的版本,編譯器需要掌握函數(shù)模板或類模板成員函數(shù)的定義

總結(jié)與非模板代碼不同,模板的頭文件通常既包括聲明也包括定義,即函數(shù)模板和類模板成員函數(shù)的定義通常放在頭文件中

大多數(shù)編譯錯(cuò)誤出現(xiàn)的時(shí)機(jī) 

  • 第一階段,編譯模板本身時(shí),該時(shí)期所出現(xiàn)的錯(cuò)誤大多數(shù)為語法錯(cuò)誤
  • 第二階段,編譯器遇到模板使用時(shí)
  • 第三階段,模板實(shí)例化時(shí),而只有在這個(gè)階段才能發(fā)現(xiàn)類型相關(guān)的問題

**注意事項(xiàng):**保證傳遞給模板的實(shí)參支持模板所要求的操作,以及這些操作在模板中能正確的工作,是調(diào)用者的責(zé)任

類模板

類模板是用來生成類的藍(lán)圖的。與函數(shù)模板不同之處是,編譯器不能為類模板推斷模板參數(shù)類型。 所以我們必須在模板名后的尖括號中提供額外的信息——用來替代模板參數(shù)的模板實(shí)參列表

vector<int> vi;
deque<double> dd;
pair<string,int> key_val;

定義類模板

template<typename T>
class T_vector {
public:
	typedef T value_type;
    // 構(gòu)造函數(shù)
    T_vector() =default;
    T_vectot(std::initializer_list<T> il);
    // 容器的元素?cái)?shù)目
    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;
}

類似函數(shù)模板,類模板以關(guān)鍵字template開始,后跟模板參數(shù)列表。在類模板(及其成員)的定義中,我們將模板參數(shù)當(dāng)作替身,代替使用模板時(shí)用戶需要提供的類型或值

**注:**一個(gè)類模板的每一個(gè)實(shí)例都形成一個(gè)獨(dú)立的類,而類模板的每個(gè)實(shí)例都有其自己版本的成員函數(shù)

? 所以,我們可能會出現(xiàn)一個(gè)單一模板并不能滿足所有類型的需求,而模板特例化就出現(xiàn)了

類模板成員函數(shù)的實(shí)例化

? 默認(rèn)的情況下,一個(gè)類模板的成員函數(shù)只有在程序用到它的時(shí)候才會實(shí)例化

// 實(shí)例化T_vector和接受initializer_list<int>的構(gòu)造函數(shù)
T_vector<int> T_vi = { 0,1,2,3,4,5 };

如果一個(gè)成員函數(shù)沒有被使用,則它將不會被實(shí)例化

為什么我們需要模板特例化?

當(dāng)我們編寫單一的模板時(shí),使其對任何可能的模板實(shí)參都是最合適的,都能實(shí)例化,但者往往都是過于理想化的情況。在某些特殊的情況下,通用的模板的定義可能對特定的類型是不合適的,通用定義的模板可能會出現(xiàn)編譯失敗或者做得不夠完善的情況。

故,當(dāng)我們不能(或者不希望)使用模板版本的時(shí)候,可以定義類或函數(shù)模板的一個(gè)特例化版本

定義函數(shù)模板特例化

// 原先cmp函數(shù)的特殊版本,用來處理特殊的字符數(shù)組的指針template<>int cmp(const char* const& p1,const char* const& p2) {    return strcmp(p1,p2);}// 原先cmp函數(shù)的特殊版本,用來處理特殊的字符數(shù)組的指針
template<>
int cmp(const char* const& p1,const char* const& p2) {
    return strcmp(p1,p2);
}

函數(shù)重載與模板特例化的區(qū)別

? 當(dāng)定義函數(shù)模板的特例化版本時(shí),我們本質(zhì)上接管了編譯器的工作。即,我們?yōu)樵鹊哪0宓钠渲幸粋€(gè)特殊的實(shí)例提供了定義。簡而言之,特例化的本質(zhì)是實(shí)例化一個(gè)模板,而非重載它,因此特例化并不影響函數(shù)匹配

注意事項(xiàng):

  • 為了特例化一個(gè)模板,原模版的聲明必須在作用域中
  • 在任何使用模板實(shí)例的代碼之前,特例化版本的聲明也必須在作用域中
  • 所有同名模板的聲明應(yīng)該放在前面,然后是這些模板的特例化版本

類模板部分特例化

與函數(shù)模板不同的是,類模板的特例化不必為所有模板參數(shù)提供實(shí)參。一個(gè)類模板的部分特例化本身是一個(gè)模板,使用它時(shí)用戶還必須為那些在特例化版本中指定的模板參數(shù)提供實(shí)參

我們只能部分特例化類模板,而不能部分特例化函數(shù)模板

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • C++如何用數(shù)組模擬鏈表

    C++如何用數(shù)組模擬鏈表

    大家好,本篇文章主要講的是C++如何用數(shù)組模擬鏈表,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C語言實(shí)現(xiàn)順序表的全操作詳解

    C語言實(shí)現(xiàn)順序表的全操作詳解

    順序表,全名順序存儲結(jié)構(gòu),是線性表的一種,線性表用于存儲邏輯關(guān)系為“一對一”的數(shù)據(jù),順序表自然也不例外,不僅如此,順序表對數(shù)據(jù)的物理存儲結(jié)構(gòu)也有要求,跟隨下文來具體了解吧
    2022-04-04
  • C++實(shí)現(xiàn)圖書館系統(tǒng)

    C++實(shí)現(xiàn)圖書館系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)圖書館系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++/Php/Python/Shell 程序按行讀取文件或者控制臺的實(shí)現(xiàn)

    C++/Php/Python/Shell 程序按行讀取文件或者控制臺的實(shí)現(xiàn)

    下面小編就為大家?guī)硪黄狢++/Php/Python/Shell 程序按行讀取文件或者控制臺的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • C++ LeetCode1805字符串不同整數(shù)數(shù)目

    C++ LeetCode1805字符串不同整數(shù)數(shù)目

    這篇文章主要為大家介紹了C++ LeetCode1805字符串不同整數(shù)數(shù)目,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • C++面向?qū)ο笾鄳B(tài)的實(shí)現(xiàn)和應(yīng)用詳解

    C++面向?qū)ο笾鄳B(tài)的實(shí)現(xiàn)和應(yīng)用詳解

    相信大家都知道面向?qū)ο蟮娜筇匦允欠庋b,繼承和多態(tài),下面這篇文章主要給大家介紹了關(guān)于C++面向?qū)ο笾鄳B(tài)的實(shí)現(xiàn)和應(yīng)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-09-09
  • C或C++報(bào)錯(cuò):ld returned 1 exit status報(bào)錯(cuò)的原因及解決方法

    C或C++報(bào)錯(cuò):ld returned 1 exit status報(bào)錯(cuò)的原因及解

    這篇文章主要介紹了C或C++報(bào)錯(cuò):ld returned 1 exit status報(bào)錯(cuò)的原因及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • C++實(shí)現(xiàn)簡單職工信息管理系統(tǒng)

    C++實(shí)現(xiàn)簡單職工信息管理系統(tǒng)

    本文給大家分享的是使用C++實(shí)現(xiàn)簡單的職工信息管理系統(tǒng)的代碼,本系統(tǒng)采用了面向?qū)ο蟮某绦蛟O(shè)計(jì)方法,所有的方法均以類為基礎(chǔ),感興趣的小伙伴們可以參考一下
    2015-08-08
  • C語言數(shù)組詳細(xì)介紹

    C語言數(shù)組詳細(xì)介紹

    大家好,本篇文章主要講的是C語言數(shù)組詳細(xì)介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C語言詳解數(shù)據(jù)結(jié)構(gòu)與算法中枚舉和模擬及排序

    C語言詳解數(shù)據(jù)結(jié)構(gòu)與算法中枚舉和模擬及排序

    枚舉和模擬其實(shí)是沒什么算法可言的,大多數(shù)都是按照題目意思去寫,這里提供快排和歸并的兩個(gè)模板,感興趣的朋友來看看吧
    2022-04-04

最新評論