首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ 模板詳解(一):函數模板、類模板、模板參數全面指南

     編輯:C++ 入門

模板核心概念

模板:對類型進行參數化的工具,實現與類型無關的代碼。

  • 函數模板:僅參數類型不同
  • 類模板:僅數據成員和成員函數類型不同

限制:模板聲明/定義只能在全局、命名空間、類作用域,不能在函數內部(如 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 類似...

三、模板參數的三種類型

1. 類型參數

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。

2. 非類型參數(內置類型參數)

template <class T, int N> class Buffer { T data[N]; };
  • 定義內部是 常量值
  • 允許類型:整型、指針、引用(不允許 float、string、類對象)
  • 實參必須是編譯期常量表達式:
    • 全局變量/對象的地址或引用
    • const 變量
    • sizeof 結果
    • 局部變量、全局指針/變量/對象 不是 常量表達式

3. 模板模板參數

參數本身是模板,如 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;

總結

  • 函數模板依賴實參推演,類模板需顯式指定類型
  • 非類型參數擴展了模板表達力(如數組大小、編譯期常量)
  • 模板定義通常放在頭文件,聲明與實現不可分離
  • 掌握模板參數分類與轉換規則,是精通 C++ 泛型編程的基石
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved