EasyC++模板顯式具體化
1.模板顯式具體化
前文當中說了,模板函數(shù)雖然非常好用,但是也存在一些問題。比如有的操作并不是對所有類型都適用的,針對這種情況C++提供了一個解決方案,就是針對特定類型提供具體化的模板定義。這里的具體可以理解成類型的具體。
我們來看一個C++ Primer當中的例子,假設(shè)現(xiàn)在我們有一個結(jié)構(gòu)體叫做job:
struct job { string name; double salary; int floor; }
對于結(jié)構(gòu)體是可以整體賦值的,所以之前的Swap
函數(shù)對它一樣適用。
template <typename T> void Swap(T &a, T &b) { T temp = a; a = b; b = temp; }
但我們現(xiàn)在希望在交換結(jié)構(gòu)體的時候,只是交換salary
和floor
這兩個字段,把name
保持不變。由于我們希望引入邏輯變化,所以直接調(diào)用Swap函數(shù)就不可行了。
當然我們可以不用函數(shù)模板,直接重載函數(shù):
void Swap(job &a, job &b) { // swap為std自帶的交換函數(shù),在algorithm頭文件中 swap(a.salary, b.salary); swap(a.floor, b.floor); }
由于C++當中規(guī)定,非函數(shù)模板的優(yōu)先級大于函數(shù)模板,所以我們在對job結(jié)構(gòu)體調(diào)用Swap函數(shù)的時候,會優(yōu)先使用這個。
除此之外,我們還可以提供一個具體化的模板函數(shù):
template <> void Swap<job> (job &a, job &b) { swap(a.salary, b.salary); swap(a.floor, b.floor); }
這個函數(shù)的寫法看起來有些特殊,我們在函數(shù)類型之前加上了template <>,在函數(shù)名后面又跟上了<job>。它表示的是這是一個函數(shù)模板的顯式具體化,也可以理解成為之前的函數(shù)模板提供一個job類型的版本。C++當中規(guī)定顯式模板函數(shù)的優(yōu)先級高于普通模板函數(shù)。
2.實例化和具體化
關(guān)于函數(shù)模板,還有一個很重要的概念,就是實例化。
我們在編寫代碼時,如果只是編寫了函數(shù)模板本身,編譯器是不會為我們生成函數(shù)的定義的。當編譯器使用模板為特定的類型生成函數(shù)定義時,就會得到一個模板的實例。這個概念有點像是Python里的元類,元類的實例是另外一個類。
比如我們定義了一個函數(shù)模板:
template <typename T> void Swap(T &a, T &b) { T temp = a; a = b; b = temp; }
當我們調(diào)用它,傳入兩個int類型的時候,編譯器就會生成一個實例,這個實例使用的類型是int。當我們使用double類型的參數(shù)又一次調(diào)用的時候,編譯器會繼續(xù)生成double
類型的實例。這個生成實例的過程是不可見的,所以被稱為隱式實例化。
在早年的C++版本當中只支持隱式實例化,但現(xiàn)在C++允許顯示實例化。也就意味著我們可以手動命令編譯器創(chuàng)建特定的實例,比如Swap<int>()
。語法是通過<>聲明指定模板類型,并且在聲明之前加上關(guān)鍵字template,如:
template void Swap<int>(int, int);
這個語法看起來和顯式具體化非常相似,顯式具體化的寫法是:
template<> void Swap<int>(int &, int &); template<> void Swap(int &, int &);
看起來非常相似,但是含義是完全不同的。顯式具體化的含義是對于某特定類型不要使用原模板生成函數(shù),而應(yīng)專門使用指定的函數(shù)定義。而顯式實例化是使用之前的模板函數(shù)的定義的,只不過是手動觸發(fā)編譯器創(chuàng)建函數(shù)實例而已。
對了,我們不能同時在一個文件中,使用同一種類型的顯式實例化和顯式具體化,這會引起報錯。
我們?nèi)绻烙涳@式實例化的聲明,的確很容易和具體化混淆。但我們可以在代碼當中直接使用,直接使用的形式則要簡單許多,只需要通過<>表明類型即可。
例如:
template <typename T> T Add(T a, T b) { return a + b; } int main() { int a = 3; double b = 3.5; cout << Add<double>(a, b) << endl; }
在上面這段代碼當中,我們通過給Add函數(shù)加上了<double>
來手動創(chuàng)建了一個接受double類型的函數(shù)。需要注意的是,我們傳入的a是一個int類型。所以編譯器會執(zhí)行強制類型轉(zhuǎn)換,將它轉(zhuǎn)換成double
傳入。
到此這篇關(guān)于C++模板顯式具體化的文章就介紹到這了,更多相關(guān)C++模板顯式具體化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法
這篇文章主要介紹了詳解如何配置CLion作為Qt5開發(fā)環(huán)境的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Qt5連接并操作PostgreSQL數(shù)據(jù)庫的實現(xiàn)示例
本文主要介紹了Qt5連接并操作PostgreSQL數(shù)據(jù)庫的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12C語言中strcpy()函數(shù)的具體實現(xiàn)及注意事項
C語言庫函數(shù)char *strcpy(char *dest, const char *src)把src所指向的字符串復(fù)制到dest,下面這篇文章主要給大家介紹了關(guān)于C語言中strcpy()函數(shù)的具體實現(xiàn)及注意事項的相關(guān)資料,需要的朋友可以參考下2022-11-11C++中string轉(zhuǎn)換為char*類型返回后亂碼問題解決
這篇文章主要介紹了C++中string轉(zhuǎn)換為char*類型返回后亂碼問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07