模板相關知識點

2021-09-26 11:05:00 字數 4184 閱讀 3024

模板就是乙個模具,通過這個模具我們倒入不同材質的東西,澆築成了乙個我們想要的那個材質的物品

這個材質在我看來就是我們的引數型別,我們各種屬性的型別.

模板是**復用的一種手段,是泛型程式設計的基礎,所謂的泛型程式設計就是編寫與型別無關的**

函式模板的寫法

template函式型別 函式名字( t 函式的引數名字) 

{}templatet add(t right,t left)

int main ()

在編譯的期間,對於模板函式的型別,我們的編譯器會做出引數的型別推演,對這些引數推演生成對應型別的函式,以供呼叫,比如上面的函式,我們的編譯器對我們的實參型別做出推演,這個時候,將t 確定為int型別,讓後生成乙份專門處理int型別的**.

函式模板的匹配規則

當函式模板和同名函式模板同時存在的時候這個函式模板可以被例項化為非模板函式

對於非模板函式和同名的函式模板,如果其他條件都相同,在呼叫時候,會有限呼叫非模板函式而不會從該模板產生出乙個例項,如果模板有更好的匹配的函式,那麼將會選擇模板

函式模板並不是真正的函式,是編譯器生成**的模具,我們真正在執行函式的時候呼叫的是我們生成的函式

所以我們在使用函式模板的時候有兩步

1.建立函式模板

2.正確的呼叫函式的模板

除了有函式的模板,我們的類模板在實際的用途中還是非常的常見的

類模板的基礎寫法

最後我們的析構函式是在我們類外寫的,寫的時候我們需要在類裡面進行宣告,在類外加上作用域符號

templatecalss 類名 

{};//下面模擬一下vector模板

namespace test

size_t size()

void push_back(t data);

t& operator(size_t pos)

~vector();

private:

t* _pdata;

size_t _size;

size_t _capacity;

}; templatevector::~vector()

_size = _capacity = 0;

} templatevoid vector::push_back(t data){}

}

類模板的顯式例項化需要在類模板名字後面跟**<>**,然後將例項化的型別放在<>中即可,類模板名字不是真正的類,例項化以後的結果才是真真的類,就像我們剛才在使用vector類一樣

類模板隱式例項化指的是在使用模板類時才將模板例項化,相對於類模板顯示例項化而言的。考察如下程式。

#include using namespace std;

templateclass a

void print()

函式模板的隱式例項化/顯式例項化

函式模板的隱式例項化值指的是讓編譯器根據實參推演模板引數的實際型別

顯式的例項化就是像我們的類模板例項化一樣,在函式的名字後面加<>註明型別即可

templatet add(t right, t left) 

int main()

執行了add函式的時候,前面兩條函式我們的編譯器都可將引數推演出來,雖然我們並沒有給出例項化出型別,但是第三個函式就不行了,在模板中我們的編譯器一般不會進行型別轉換的操作.因為一旦轉換出了問題,編譯器就需要背黑鍋

還有一種簡介呼叫函式的情況,也可以完成函式模板的例項化。所謂的簡介呼叫是指將函式入口位址傳給乙個函式指標,通過函式指標完成函式呼叫。如果傳遞給函式指標不是乙個真正的函式,那麼編譯器就會尋找同名的函式模板進行引數推演,進而完成函式模板的例項化。參考如下示例。

#include using namespace std;

template void func(t t);

****

浮點型,類物件,以及字符集不允許被認作非型別模板引數的

非型別的模板引數必須在編譯期間就可以確定結果

特化就是引數型別設定為你想要的型別這不過這個模板得先建立好在模板的上面的引數進行特殊化處理

對於函式模板的特化

必須得有乙個基礎的函式模板

關鍵字後面template後面必須接一堆尖括<>

函式名字後面跟一對尖括號,尖括號後面跟的是需要特化的型別

函式形參表:必須要和我們模板函式的基礎引數型別相同,

templatebool isequal(t& left, t& right) 

template<>

bool isequal(char*& left, char*& right)

在對函式模板進行特化的時候,其實他是不如我們給出普通函式的效果好的

類模板特化的幾種方式:

全特化模板中的引數型別全都確定下來

偏特化對引數的型別進行條件的限制,確定部分的引數型別

引數部分特化

對引數進行進一步限制而定特殊化處理比如指標或者引用型別

//基礎的模板需要給出來

templateclass date

private:

t1 _d1;

t2 _d2;

};//全特化,將所有型別進行特殊化處理

template<>

class date

private:

int _d1;

char _d2;

};// 部分特化,將部分型別進行特殊化的處理

templateclass date

private:

t1 _d1;

char _d2;

};//引數的更近一步的限制

template<>

class date

private:

int* _d1;

char* _d2;

};

萃取就是提取合適的型別做出相應型別的操作,比如說對於變數的拷貝,當他是自定義型別的時候,就需要我們來做出相應的操作了

下面我們用乙個通用的拷貝函式舉例子,我們的自定義型別是string型別

c++型別萃取

//定義乙個string類,這類由我們來實現,因為牽扯到深淺拷貝的問題

class string

_str = new char(strlen(str) + 1);

strcpy(_str, str);

} string(const string& s):_str(new char[strlen(s._str)+1])

} string& operator=(const string& s)

return *this;

} ~string()

delete_str;

_str = nullptr;

}private:

char *_str;

};//型別萃取就是類模板特化的應用

template//通用拷貝函:任意的型別都可以進行拷貝

void copy(t* dst, t* src, size_t size) */

if (typetraits::ispodtype::get())

else }}

//這兩個類裡面都有靜態的成員函式,這時候呼叫一下,就可以完成這個區分,在編譯期間我們的編譯器就已經

//將t的型別做出了區分

struct falsetype

};struct truetype

};//型別模板

templatestruct typetraits ;

//型別模板的特化

template<>

struct typetraits;

template<>

struct typetraits;

對於模板的分離編譯我是學習的這個鏈結

相關知識點

nweb inf uclasses uweb.xml ulib n 從httpservlet 繼承,重寫doget dopost方法 n部署web.xml n 只有乙個物件 n 第一次請求的時候被初始化,只一遍 n 初始化後先呼叫init 方法,只一遍 n 每個請求,呼叫一遍service serv...

Camera相關知識點

1 camera涉及到的概念 1.1 preview capture video preview 預覽 capture 拍照 video 錄影 1.2 幀率 快門 幀率 frame rate 用於測量顯示幀數的量度。所謂的顯示單位為每秒顯示的幀數,簡稱fps或hz 快門 shutter。快門是攝像器...

CURL相關知識點

1,建立乙個curl的會話資源 ch curl init 設定url,引數傳遞出來的時候 curl setopt ch,curlopt url,url 使用post提交的資料 curl setopt ch,curlopt post,1 if post data 設定是否將響應結果存入變數,1或者tr...