C++ 中的 Template 大致有三種用法,Function Template、Specialization,和 Class Template。
Function Template 就是保留函式的參數型態,或函式內的變數型態,等到執行時再依主程式傳入的參數來決定,以提高函式的泛用性,例如
#include <iostream>
template <typename T>
void swap(T& a,T& b) {
T tmp=a;
a=b;
b=tmp;
}
template <typename T1, typename T2>
T1 max(T1 x, T2 y)
{
return (x>y) ? x : y;
}
int main() {
float x=3.14, y=98.9;
swap(x,y);
std::cout << x << " " << y << " " << max(x,99);
int a=1, b=2;
swap(a,b);
std::cout << a << " " << b << " " << max(a,b);
return 0;
}
上面第一個 swap 函式僅以主程式傳來的一種參數型態運作,所以 a b 參數的型態必須相同,否則會產生編譯錯誤。第二個 max 函式則接受兩種參數型態,T1 與 T2 型態可以相同或不同(不考慮是否影響程式運算),並以T1參數型態之值回傳。template <typename T>的寫法可改為 template <class T>,兩者功能一樣。
Specialization 特化,就是例外處理,由於 Function Template 讓函式產生泛用性,但若有需要對特定的資料型別進行其他處理,則可宣告一個同名 Template 函式並指定參數型別,來撰寫例外處理程式
#include <iostream>
template <typename T> //樣板函式1
void swap(T& a,T& b) {
T tmp=a;
a=b;
b=tmp;
}
template <> //樣板函式2
void swap<int>(int& a,int& b) {
a=b=0;
}
int main() {
float a=50, b=100;
swap(a,b); //float 叫用樣板函式1
std::cout << a << " " << b << std::endl;
int x=50, y=100;
swap(x,y); //Specialization, int 叫用樣板函式2
std::cout << x << " " << y << std::endl;
return 0;
}
第三種 Class Template 在 "Class template 類別樣版/模板" 這篇已有介紹,以下針對一般 Class 和 Class Template 之間繼承情況做一整理。
按照一般 class 與 class template 分別為父類別、衍生類別的排列組合有四
父類別 | 衍生類別 |
class | class |
class | template |
template | class |
template | template |
以上四種組合在 C++ 中都是允許的,以下程式即示範各種繼承關係
#include <iostream>
class baseClass1 {
public:
int a;
};
template <typename T> class baseClass2 {
public:
T b;
};
class sonClass1 : public baseClass1 {
public:
int c;
};
class sonClass2 : public baseClass2<float> {
public:
int d;
};
template <typename T> class sonClass3 : public baseClass1 {
public:
T e;
};
template <typename T> class sonClass4 : public baseClass2<int> {
public:
T f;
};
template <typename T> class sonClass5 : public baseClass2<T> {
public:
T g;
};
int main()
{
baseClass1 b1;
baseClass2<float> b2;
sonClass1 s1;
sonClass2 s2;
sonClass3<float> s3;
sonClass4<float> s4;
sonClass5<float> s5;
b1.a=1; //int
b2.b=3.14; //T
s1.a=1; //int
s1.c=1; //int
s2.b=3.14; //T
s2.d=1; //int
s3.a=1; //int
s3.e=3.14; //T
s4.b=3.14; //T int
s4.f=3.14; //T
s5.b=3.14; //T
s5.g=3.14; //T
std::cout << b1.a << std::endl;
std::cout << b2.b << std::endl;
std::cout << s1.a << std::endl;
std::cout << s1.c << std::endl;
std::cout << s2.b << std::endl;
std::cout << s2.d << std::endl;
std::cout << s3.a << std::endl;
std::cout << s3.e << std::endl;
std::cout << s4.b << std::endl;
std::cout << s4.f << std::endl;
std::cout << s5.b << std::endl;
std::cout << s5.g << std::endl;
return 0;
}
沒有留言:
張貼留言