c++++模板參數分為類型參數和非類型參數。類型參數用于抽象數據類型,使模板能接受不同類型的輸入,適用于變量類型、返回值或通用容器;非類型參數傳遞具體值,必須是編譯時常量表達式,如整型、指針或引用,c++17支持auto推導,c++20部分支持浮點數。兩者關鍵區別在于類型參數影響實例化類型,而非類型參數影響行為或大小且需編譯期確定。使用時優先選類型參數,若需編譯期數值則用非類型參數,并注意其限制與生命周期問題。
C++模板參數的類型可以分為兩大類:類型參數(type parameters)和非類型參數(non-type parameters)。理解它們的區別和使用場景,能幫助我們寫出更靈活、高效的泛型代碼。
類型參數:用于抽象數據類型
類型參數是我們最常見的一種模板參數形式,它的作用是讓模板能夠接受不同的數據類型作為輸入,從而實現通用邏輯。
比如:
立即學習“C++免費學習筆記(深入)”;
template<typename T> class Vector { // ... };
這里的 T 就是一個類型參數,你可以用 int、double、自定義類等任何合法類型來實例化這個模板。
常見使用方式包括:
- 用作變量類型
- 作為函數返回值或參數類型
- 構造通用容器或算法
需要注意的是,類型參數不能是某些特殊類型,例如帶有特定限定符的數組、引用等,除非在模板內部做了特殊處理。
非類型參數:傳遞具體值而非類型
非類型參數允許我們將具體的值作為模板參數傳入。這些值必須是編譯時常量表達式。
例如:
template<int N> class Array { int data[N]; };
在這個例子中,N 是一個非類型參數,表示數組的大小。這樣可以在編譯時就確定數組長度,避免運行時動態分配帶來的性能開銷。
常見支持的非類型參數包括:
但要注意,并不是所有類型的值都能作為非類型參數使用。例如浮點數就不被允許,直到 C++20 才開始部分支持。
類型參數 vs 非類型參數:關鍵區別
對比項 | 類型參數 | 非類型參數 |
---|---|---|
表示內容 | 數據類型 | 具體值 |
實例化影響 | 生成不同類型的類或函數 | 通常不改變結構,只影響行為或大小 |
編譯期要求 | 無特別限制 | 必須是常量表達式 |
靈活性 | 更高,適用于多種類型 | 適合固定模式下的變化 |
舉個例子,當你想寫一個通用的排序函數,類型參數更適合;而如果你要定義一個固定大小的數組類,非類型參數會更合適。
使用建議與注意事項
- 優先使用類型參數,除非你確實需要在編譯期決定某些具體數值。
- 注意非類型參數的值必須在編譯時已知,否則無法通過編譯。
- 使用非類型參數時,盡量避免復雜的類型,比如指針或引用,除非你清楚其生命周期和綁定關系。
- C++20 中引入了 consteval 和 constinit 等特性,使得非類型參數的使用更加靈活,但也增加了理解成本。
基本上就這些。掌握這兩類模板參數的用法,能讓你在寫模板代碼時更有底氣。