非型別模板參數支援三類:整數型別、指標、引用。關鍵限制:整數實參必須為常數表達式;指標/引用實參需具有靜態儲存期(全域/靜態變數),不能使用區域或動態物件。
//=====================================
// Name : CppPrimer.cpp
// Author : Caroline
// Description : 非型別模板參數範例
//=====================================
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
// 1. 整數非型別參數:推導字串字面值長度
template<unsigned N, unsigned M>
bool compare(const char (&p1)[N], const char (&p2)[M]) {
std::cout << "size : " << N << " " << M << std::endl;
return strcmp(p1, p2);
}
// 2. 指標非型別參數:需全域/靜態變數
template<const char* C>
void pointerT(const char* str) {
std::cout << C << " " << str << std::endl;
}
// 3. 引用非型別參數:陣列引用需精確大小
template<char (&ra)[9]>
void referenceT(const char* str) {
std::cout << ra << " " << str << std::endl;
}
// 全域變數:供指標/引用參數使用
char ca[] = "Caroline"; // 指標實參
char cr[9] = "Caroline"; // 引用實參(含結尾 \0)
// 4. 函數指標非型別參數
void f(const char* c) { std::cout << c << std::endl; }
template<void (*F)(const char*)>
void fpointerT(const char* c) {
F(c);
}
int main(void) {
// 整數參數:編譯期推導陣列大小
if (compare("Caroline", "Wendy")) {
std::cout << "Caroline is long." << std::endl;
} else {
std::cout << "Wendy is long." << std::endl;
}
// 指標參數:使用全域陣列地址
pointerT<ca>("Wendy");
// 引用參數:使用全域陣列引用
referenceT<cr>("Wendy");
// 函數指標參數
fpointerT<f>("Caroline Wendy");
return 0;
}
size : 9 6 Caroline is long. Caroline Wendy Caroline Wendy Caroline Wendy
| 參數類型 | 實參要求 | 典型應用 |
|---|---|---|
| 整數 | 常數表達式 (constexpr) | 陣列大小、緩衝區長度、編譯期常數 |
| 指標 | 靜態儲存期物件地址 | 全域變數、函數地址、字串字面值 |
| 引用 | 靜態儲存期物件 | 全域陣列、單例物件 |
| 函數指標 | 函數地址 | 回調函數、策略模式、編譯期分派 |
template <typename T, std::size_t N>
class Array {
T data[N];
public:
// ...
};
Array<int, 10> arr; // 編譯期固定大小陣列