国产激情在线视频_欧美一区2区三区4区公司二百_老牛嫩草一区二区三区眼镜_亚洲区在线_欧美日韩精品网站_亚洲成人伦理

網站首頁 綜合導航 全能搜索 網站地圖 聯系我們

首頁 > 教程 > 模板知識

模板基礎知識之函數模板

  • 分類 : 模板知識
  • 編輯 : 大寶123
  • 發布 : 10-27
  • 閱讀 :777

一、簡介

該篇主要內容為介紹函數模板以及函數模板的基本用法。

二、編程環境

系統:Windows11
IDE:Visual Studio2022
項目名字:funcTemp

三、內容

1.基本范例

1.1函數模板的作用

舉例說明:編程過程中,數據類型千奇百怪,僅表示數字的常見的就有int,float,double等多種類型。這些數字在數學中,都可以進行相加,相減,相乘,相除,多次方運算等等多種運算模式。但是在計算機中,并不能一概而論,每種不同的數據類型,計算機都很較真的做了區分,int和int進行計算,double和double進行計算。拿減法來說,就會產生以下的代碼。

int Sub(int a, int b)
{
    return a - b;
}
double Sub(double a, double b)
{
    return a - b;
}

如上面代碼所示,一個減法,卻要寫出兩個函數,如果是更復雜的運算,函數內容更多,幾十行甚至上百行代碼,達成同一個目的,僅僅因為類型不同,就需要重寫一遍函數,就會造成代碼冗余,不好看,使得工程變得非常龐大。為了解決這個問題所以我們需要模板。

1.2函數模板的舉例

接著上面的例子,減法運算,我們可以用一個函數解決

template <typename T>
T Sub(T a, T b)
{
    return a - b;
}

調用時,類型T會被編譯器自動的,識別為所給參數的類型。
調用舉例

int y = Sub(5, 3);

調用驗證,使用VS自帶的工具,搜索Developer Command Prompt for vs2022,打開后進入命令行,進入到工程編譯的文件夾路徑下。會生成一個funcTemp.obj的文件。使用dumpbin命令來驗證調用過程中,編譯器自動識別類型T的正確性

dumpbin /all funcTemp.obj > funcTemp.txt

就會在該文件夾下生成一個funcTemp.txt文件。查看funcTemp.txt文件。搜索函數名,就可以看到,sub()函數,自動的把T類型識別為了int類型

COMDAT; sym= "int __cdecl Sub<int>(int,int)" (??$Sub@H@@YAHHH@Z)

1.3函數模板說明

1.template :表示函數模板的開始,是C++中的關鍵字
2.typename:typename修飾的是類型T,語法規定的寫法。也可以用class代替,不過我的習慣是函數模板中用typename,在類模板中用class。
3.T:T表示一個類型,可以是任意的,也可以是X,Y,L等等
4.函數體中,與普通函數類似,只需要主要如果是T類型的,就一定寫T就好。

template <typename T>                       
T Sub(T a, T b)
{
    return a - b;
}

1.4多個類型的函數模板使用

上面介紹的內容中,T要么是指代了int要么是指代了double,如果是int-double呢,或者int+double+int呢。所以函數模板也可以“傳入多個T類型”。簡單的例子如下。

template <typename T,typename U,typename K>                       
T Sub(T a, U b, K c)
{
    return a - b - c;
}

2.模板函數的重載

普通函數可以重載,只要參數數量不同,參數類型不同,即可完成重載。與函數重載非常類似。下面用代碼說明。

template<typename T>
void myFunc(T a)
{
    std::cout << "myFunc(T a) is done" << std::endl;
}

template<typename T>
void myFunc(T* a)
{
    std::cout << "myFunc(T* a) is done" << std::endl;
}

上面模板函數完成了重載,第一個傳入的是T類型的參數,第二個傳入的是T*類型參數。參數類型不同,就是一個重載的(模板)函數。

3.特化

3.1.全特化

模板函數屬于是泛化,具有不確定性,廣泛性的模式,與之相反的,全特化,就是確定的,指定的模式。
寫一個模板函數

template<typename T,typename U>
void myFunc(T* a , U& b)
{
    std::cout << "myFunc(T* a , U& b) is done" << std::endl;
}

這里的T與U都是不確定的,在調用的時候,編譯器自動編譯確定類型。
下面寫一個全特化版本

template<>
void myFunc(char* a , int& b)
{
    std::cout << "myFunc(char* a , int& b) is done" << std::endl;
}

這里注意看,<>里面是空的!,函數體里確定了,第一個參數是char*類型,第二個參數是int& 類型。但是要知道的是,看起來挺像重載,但記住,全特化不等于重載。全特化只是實例化了一個函數模板。

3.2.偏特化

在模板函數中,偏特化并不方便實現,只能通過重載的方式來實現,但是很少會在實際開發中使用到,這里不過多說明(真的用不到,類里面才會比較方便使用)。

四、注意點

1.不要讓模板函數有不確定的類型

注意看以下代碼。

template <typename T,typename U,typename V>
V Add(T a, U b)
{
    return a + b;
}
int main()
{
    std::cout << Add(2 , 3.5) << std::endl;
    return 0;
}

編譯時會報錯,原因是返回類型V并不能被編譯器推斷出來。改進的方法有兩種,我比較傾向于第二種。
方法一:指定返回值類型,并且將返回值類型放到第一位,注意對比上面的代碼,V被放到了第一位,調用的時候也顯式的指出了V的類型。

template <typename V,typename T,typename U>
V Add(T a, U b)
{
    return a + b;
}
int main()
{
    std::cout << Add<double>(2 , 3.5) << std::endl;
    return 0;
}

方法二:使用auto關鍵字。這樣返回值類型就不用管傳入的類型,讓編譯器自己去推斷。會更加方便,我比較傾向于這種方式。

template <typename T,typename U>
auto Add(T a, U b)
{
    return a + b;
}
int main()
{
    std::cout << Add(2 , 3.5) << std::endl;
    return 0;
}

2.使用隱式轉換,改變傳入的參數

在一些開發過程中,傳入的參數可能不是我們想要的參數,總會多一些煩人的小數點,我們可以用隱式轉換,改變傳入的參數類型,下面函數,傳入的類型為double類型,我們不想要2.3,我們只要2,就必須顯式的指出傳入類型。

template < typename U>
auto MySquare(U a)
{
    return a * a;
}
int main()
{
    std::cout << MySquare(2.3) << std::endl;
    std::cout << MySquare<int>(2.3) << std::endl;
    return 0;
}

3.函數調用的優先級

一個程序中,可以有函數模板,可以特化,可以有功能相同的普通函數,那么編譯器會優先調用哪一個類型的函數呢?

//模板函數
template <typename T>
void Temp(T a)
{
     std::cout << "temp  is run" << std::endl;
}
//全特化
template <>
void Temp(int a)
{
     std::cout << "spacial temp is run" << std::endl;
}
//功能相同的普通函數
void Temp(int a)
{
     std::cout << "general func  is run" << std::endl;
}

int main()
{
    Temp(8);
    return 0;
}

看結果,是普通函數被調用了,我們把普通函數屏蔽了之后,是特化的模板函數被調用了。所以可以得出結論,函數調用的順序是普通函數 > 特化的模板函數 > 泛化的模板函數

五、總結

模板函數的基礎使用方法,基本上就這么多了,如果有錯誤歡迎指正。這是一些看王建偉老師編寫的《C++新經典 模板與泛型編程》*一書過程中的理解。歡迎交流。



作者:唐予清
鏈接:https://www.jianshu.com/p/6335ed2ff0a4
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
主站蜘蛛池模板: 亚洲成人三级 | 久久久久久精 | 亚洲经典一区二区三区 | 蜜桃视频麻豆女神沈芯语免费观看 | 一线天逼| 日韩久久久久久 | 色综合久久久久 | 日本a v网站 | 成人激情视频在线观看 | 日本一本视频 | 六月色婷婷 | 午夜日韩 | 久久国产精品成人免费观看的软件 | 男女免费在线观看视频 | avhd101在线成人播放 | 久久久久国产 | 久久久久无码国产精品一区 | 中文字幕免费视频观看 | 成人韩免费网站 | 免费一级毛片 | 国产午夜小视频 | 亚洲欧洲精品成人久久奇米网 | 久久二区三区 | 日韩综合一区 | 久久精品国产精品 | 亚洲 国产 另类 精品 专区 | 国产成人av一区二区 | 亚洲欧美视频一区 | 99久久综合狠狠综合久久 | 亚洲 中文 欧美 日韩 在线观看 | 国产高清久久久 | 久草在线在线精品观看 | 欧美一区二区在线观看 | 色爱区综合五月激情 | 日韩精品中文字幕在线播放 | 欧美日韩国产在线看 | 久久99精品久久久久久琪琪 | 欧美日韩国产一区二区三区不卡 | 免费aaa | 免费成人在线视频网站 | 日韩欧美一级在线 |