文章目錄
-
- 1 多參數類模闆
- 2 類模闆特化
- 3 函數模闆特化
- 4 小結
- 類模闆可以定義任意多不同的類型參數

類模闆可以被特化
- 指定類模闆的特定實作
- 部分類型參數必須顯示指定
- 根據類型參數分開實作類模闆
- 編譯器自動擇優選擇
類模闆特化可以分為部分特化和完全特化兩種類型
- 部分特化–>用特定規則限制類型參數
- 完全特化–>完全顯示指定類型參數
程式設計實驗:類模闆特化
// 44-1.cpp
#include<iostream>
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<typename T1, typename T2>
class Test<T1*, T2*> // 關于指針的特化實作
{
public:
void add(T1* a, T2* b)
{
cout << "void add(T1* a, T2* b)" << endl;
cout << *a + *b << endl;
}
};
template<typename T>
class Test<T, T> // 當 Test 類模闆的兩個類型參數完全相同時,使用這個實作
{
public:
void add(T a, T b)
{
cout << "void add(T a, T b)" << endl;
cout << a + b << endl;
}
void print()
{
cout << "class Test<T, T>" << 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;
}
};
int main()
{
Test<int, float>t1; // 必須顯示指明每一個類型參數
Test<long, long>t2;
Test<void*, void*>t3;
t1.add(1, 2.5);
t2.add(5, 5);
t2.print();
t3.add(NULL, NULL);
Test<int*, double*>t4;
int a = 1;
double b = 0.1;
t4.add(&a, &b);
return 0;
}
- 上面的代碼先定義了一個模闆類,然後給出了三個特化實作。特化本質上是同一個類模闆。編譯器總是選擇最比對的進行實作。
- t1.add(1, 2.5); 調用 class Test
- t2.add(5, 5); 調用 class Test<T, T>
- t3.add(NULL, NULL); 調用 class Test<void*, void*>
- t4.add(&a, &b); 調用 class Test<T1*, T2*>
$ g++ 44-1.cpp -o 44-1
$ ./44-1
void add(T1 a, T2 b)
3.5
void add(T a, T b)
10
class Test<T, T>
void add(void* a, void* b)
Error to add void* param...
void add(T1* a, T2* b)
1.1
注意事項:
- 特化本質上屬于同一類模闆,隻是模闆的分開實作
- 特化類模闆的使用方式是統一的,必須顯示指定每一個類型參數
函數模闆隻支援類型參數完全特化
程式設計實驗:函數模闆特化
// 44-2.cpp
#include<iostream>
using namespace std;
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.01, 0.01) << endl; // 指定使用模闆
cout << Equal(0.1, 0.1) << endl;
return 0;
}
- bool Equal(T a, T b) 是函數模闆,兩個浮點數比較不能直接使用 ‘==’,是以實作函數模闆特化 bool Equal(double a, double b),函數模闆隻能完全特化。二者本質上屬于同一模闆,隻是分開實作
- bool Equal(double a, double b) 是函數重載。
- Equal(1, 1) 将選擇模闆 bool Equal(T a, T b)
- Equal<>(0.01, 0.01) 使用模闆 bool Equal<double>(double a, double b)
- Equal(0.1, 0.1) 使用重載函數 bool Equal(double a, double b),
$ g++ 44-2.cpp -o 44-2
$ ./44-2
bool Equal(T a, T b)
1
bool Equal<double>(double a, double b)
1
bool Equal(double a, double b)
1