日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C++中的函数模板

發布時間:2025/4/5 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中的函数模板 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 C++中的函數模板簡介
    • 2 函數模板深入理解
    • 3 多參數函數模板
    • 4 函數重載遇到函數模板
    • 5 函數模板的特化
    • 6 數值型模板參數

1 C++中的函數模板簡介

函數模板:

  • 一種特殊的函數可用不同類型進行調用。
  • 看起來和普通函數很相似,區別是類型可被參數化。
  • 函數模板是泛型編程在C++中的應用方式之一,是C++中重要的代碼復用方式。

    函數模板語法規則:
  • template關鍵字用于聲明開始進行泛型編程。
  • typename關鍵字用于聲明泛指類型。


函數模板的使用:

  • 自動類型推導調用。
  • 具體類型顯示調用。

    函數模板使用示例:
#include <iostream> #include <string>using namespace std;template < typename T > void Swap(T& a, T& b) {T c = a;a = b;b = c; }template < typename T > void Sort(T a[], int len) {for(int i=0; i<len; i++){for(int j=i; j<len; j++){if( a[i] > a[j] ){Swap(a[i], a[j]);}}} }template < typename T > void Println(T a[], int len) {for(int i=0; i<len; i++){cout << a[i] << ", ";}cout << endl; }int main() {int a[5] = {5, 3, 2, 4, 1};Println(a, 5);Sort(a, 5);Println(a, 5);string s[5] = {"Java", "C++", "Pascal", "Ruby", "Basic"};Println(s, 5);Sort(s, 5);Println(s, 5);return 0; }

2 函數模板深入理解

編譯器從函數模板通過具體類型產生不同的函數,編譯器會對函數模板進行兩次編譯:

  • 對模板代碼本身進行編譯。
  • 對參數替換后的代碼進行編譯。

注意事項:函數模板本身不允許隱式類型轉換。

  • 自動推導類型時,必須嚴格匹配。
  • 顯示類型指定時,能夠進行隱式類型轉換。

函數模板的本質示例程序:

#include <iostream> #include <string>using namespace std;class Test {Test(const Test&); public:Test(){} };template < typename T > void Swap(T& a, T& b) {T c = a;a = b;b = c; }typedef void(FuncI)(int&, int&); typedef void(FuncD)(double&, double&); typedef void(FuncT)(Test&, Test&);int main() {FuncI* pi = Swap; // 編譯器自動推導 T 為 intFuncD* pd = Swap; // 編譯器自動推導 T 為 double// FuncT* pt = Swap; // 編譯器自動推導 T 為 Testcout << "pi = " << reinterpret_cast<void*>(pi) << endl;cout << "pd = " << reinterpret_cast<void*>(pd) << endl;// cout << "pt = " << reinterpret_cast<void*>(pt) << endl;return 0; }

3 多參數函數模板

函數模板可以定義任意多個不同的類型參數:

對于多參數函數模板:

  • 無法自動推導返回值類型。
  • 可以從左向右部分指定類型參數。


編程實驗:多參數函數模板

#include <iostream> #include <string>using namespace std;template < typename T1, typename T2, typename T3 > T1 Add(T2 a, T3 b) {return static_cast<T1>(a + b); }int main() {// T1 = int, T2 = double, T3 = doubleint r1 = Add<int>(0.5, 0.8);// T1 = double, T2 = float, T3 = doubledouble r2 = Add<double, float>(0.5, 0.8);// T1 = float, T2 = float, T3 = floatfloat r3 = Add<float, float, float>(0.5, 0.8);cout << "r1 = " << r1 << endl; // r1 = 1cout << "r2 = " << r2 << endl; // r2 = 1.3cout << "r3 = " << r3 << endl; // r3 = 1.3return 0; }

4 函數重載遇到函數模板

函數模板可以像普通函數一樣被重載:

  • C++編譯器有限考慮普通函數。
  • 如果函數模板可以產生一個更好的匹配,那么選擇模板。
  • 可以通過空模板實參列表限定編譯器只匹配模板。

    實例分析:重載函數模板
#include <iostream> #include <string>using namespace std;template < typename T > T Max(T a, T b) {cout << "T Max(T a, T b)" << endl;return a > b ? a : b; }int Max(int a, int b) {cout << "int Max(int a, int b)" << endl;return a > b ? a : b; }template < typename T > T Max(T a, T b, T c) {cout << "T Max(T a, T b, T c)" << endl;return Max(Max(a, b), c); }int main() {int a = 1;int b = 2;cout << Max(a, b) << endl; // 普通函數 Max(int, int)cout << Max<>(a, b) << endl; // 函數模板 Max<int>(int, int)cout << Max(3.0, 4.0) << endl; // 函數模板 Max<double>(double, double)cout << Max(5.0, 6.0, 7.0) << endl; // 函數模板 Max<double>(double, double, double)cout << Max('a', 100) << endl; // 普通函數 Max(int, int)return 0; }

5 函數模板的特化

函數模板只支持類型參數完全特化:

工程中的建議:當需要重載函數模板時,有限考慮使用模板特化;當模板特化無法滿足需求時,再使用函數重載!

編程實驗:函數模板的特化

#include <iostream> #include <string>using namespace std;template < typename T1, typename T2 > class Test { public:void add(T1 a, T2 b){cout << "void add(T1 a, T2 b)" << endl;cout << a + b << endl;} };/* template < > class Test < void*, void* > // 當 T1 == void* 并且 T2 == void* 時 { public:void add(void* a, void* b){cout << "void add(void* a, void* b)" << endl;cout << "Error to add void* param..." << endl;} }; */class Test_Void { public:void add(void* a, void* b){cout << "void add(void* a, void* b)" << endl;cout << "Error to add void* param..." << endl;} };template < typename T > bool Equal(T a, T b) {cout << "bool Equal(T a, T b)" << endl;return a == b; }template < > bool Equal<double>(double a, double b) {const double delta = 0.00000000000001;double r = a - b;cout << "bool Equal<double>(double a, double b)" << endl;return (-delta < r) && (r < delta); }bool Equal(double a, double b) {const double delta = 0.00000000000001;double r = a - b;cout << "bool Equal(double a, double b)" << endl;return (-delta < r) && (r < delta); }int main() { cout << Equal( 1, 1 ) << endl;cout << Equal(0.001, 0.001) << endl; // 優先使用普通函數cout << Equal<>( 0.001, 0.001 ) << endl;return 0; }

6 數值型模板參數

模板參數可以是數值型參數(非類型參數):

數值型模板參數的限制:

  • 變量不能作為模板參數。
  • 浮點數不能作為模板參數。
  • 類對象不能作為模板參數。

本質:模板參數是在編譯階段被處理的單元,因此,在編譯階段必須準確無誤的唯一確定。

利用數值型模板參數求解如下問題:最高效的求解1 + 2 + 3 + 4 + … + N的值:

#include <iostream> #include <string>using namespace std;template < typename T, int N > void func() {T a[N] = {0};for(int i=0; i<N; i++){a[i] = i;}for(int i=0; i<N; i++){cout << a[i] << endl;} }template < int N > class Sum { public:static const int VALUE = Sum<N-1>::VALUE + N; };template < > class Sum < 1 > { public:static const int VALUE = 1; };int main() {cout << "1 + 2 + 3 + ... + 10 = " << Sum<10>::VALUE << endl;cout << "1 + 2 + 3 + ... + 100 = " << Sum<100>::VALUE << endl;return 0; }

參考資料:

  • C++深度解析教程
  • 總結

    以上是生活随笔為你收集整理的C++中的函数模板的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。