模板:對類型進行參數化的工具,實現與類型無關的代碼。
限制:模板聲明/定義只能在全局、命名空間、類作用域,不能在函數內部(如 main 中)。
template <class T1, class T2, ...>
返回類型 函數名(參數列表) { 函數體 }
class 可用 typename 替換,此處無區別// swap 模板
template <class T>
void swap(T& a, T& b) {
T tmp = a; a = b; b = tmp;
}
// max 模板
template <typename T>
const T& myMax(const T& a, const T& b) {
return a > b ? a : b;
}
int main() {
cout << myMax(2.1, 2.2) << endl; // 隱式推演 double
cout << myMax<double>(2.1, 2.2) << endl; // 顯式指定 double
cout << myMax<int>(2.1, 2.2) << endl; // 顯式指定 int,實參轉換為 2
}
swap(int, int) 這樣的調用,只能通過實參推演或顯式模板實參template <class T1, class T2, ...>
class ClassName { ... };
A<int> obj1; // 一個模板參數 A<int, double> obj2; // 多個參數,用逗號分隔
A<2> obj; 錯誤,模板參數必須是類型template <class T1, class T2>
返回類型 ClassName<T1, T2>::func(參數列表) { ... }
注意:template 後的參數列表必須與類定義一致,類名需帶上模板參數。
template <class T, int MAXSIZE>
class MyStack {
T elems[MAXSIZE]; // 非類型參數作為數組大小(編譯期常量)
int size;
public:
MyStack() : size(0) {}
void push(const T&);
void pop();
T top() const;
bool empty() const { return size == 0; }
bool full() const { return size == MAXSIZE; }
};
template <class T, int MAXSIZE>
void MyStack<T, MAXSIZE>::push(const T& e) {
if (full()) throw out_of_range("stack full");
elems[size++] = e;
}
// pop, top 類似...
template <class T> void func(T a, T b); // 調用 func(2, 3.2) 編譯錯誤:T 不能同時是 int 和 double
類模板成員函數無此限制:A<int> a; a.func(2, 3.2) 運行時第二參數轉為 int。
template <class T, int N> class Buffer { T data[N]; };
const 變量sizeof 結果參數本身是模板,如 template <template <class> class Container> class Wrapper。較高級,此處略過。
| 轉換類型 | 示例 |
|---|---|
| 數組→指針、函數→指針 | template<int*> class A; int b[10]; A<b> m; |
| const 修飾符轉換 | template<const int*> class A; int b; A<&b> m; |
| 整型提升 | template<int> class A; const short b=2; A<b> m; |
| 整數轉換 | template<unsigned int> class A; A<3> m; |