C++中的函数模板
文章目錄
- 1 C++中的函數模板簡介
- 2 函數模板深入理解
- 3 多參數函數模板
- 4 函數重載遇到函數模板
- 5 函數模板的特化
- 6 數值型模板參數
1 C++中的函數模板簡介
函數模板:
- 一種特殊的函數可用不同類型進行調用。
- 看起來和普通函數很相似,區別是類型可被參數化。
- 函數模板是泛型編程在C++中的應用方式之一,是C++中重要的代碼復用方式。
函數模板語法規則: - template關鍵字用于聲明開始進行泛型編程。
- typename關鍵字用于聲明泛指類型。
函數模板的使用:
- 自動類型推導調用。
- 具體類型顯示調用。
函數模板使用示例:
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 多參數函數模板
函數模板可以定義任意多個不同的類型參數:
對于多參數函數模板:
- 無法自動推導返回值類型。
- 可以從左向右部分指定類型參數。
編程實驗:多參數函數模板
4 函數重載遇到函數模板
函數模板可以像普通函數一樣被重載:
- C++編譯器有限考慮普通函數。
- 如果函數模板可以產生一個更好的匹配,那么選擇模板。
- 可以通過空模板實參列表限定編譯器只匹配模板。
實例分析:重載函數模板
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++中的泛型编程
- 下一篇: 基金投资如何获得收益 不同基金存在一定