模板元編程(TMP)是在編譯期執行的程序,操作編譯期常量(類型、整數常量)。C++11 引入 type_traits、可變模板參數、tuple 等特性,極大增強了 TMP 的表達能力與易用性。
提供上百個編譯期元函數,分類:
is_integral, is_class, is_same, is_const 等。add_const, remove_reference, decay, add_pointer 等。conditional::type 相當於編譯期三元運算符。enable_if::type 結合 SFINAE 實現函數重載約束。integral_constant 及 true_type/false_type。#include <type_traits>
#include <iostream>
using namespace std;
int main() {
cout << is_same::value << '\n'; // 1
cout << is_same::value << '\n'; // 0
cout << is_const::value << '\n'; // 1
using T = conditional::type; // int
using U = conditional::type; // float
cout << is_same::type>::value << '\n'; // 1
cout << is_same::type>::value << '\n'; // 1
return 0;
}
template 表示 0~任意個任意類型參數。常用技巧:
func(Args... args) → func(args...)。sizeof...(Args) 獲取參數包大小。int arr[] = { (func(args), 0)... }; 實現遍歷調用。// 獲取最大值
template struct IntMax;
template struct IntMax : integral_constant {};
template
struct IntMax : integral_constant= V2 ? IntMax::value : IntMax::value)> {};
// 判斷類型包是否包含 T
template struct Contains;
template
struct Contains : conditional::value, true_type, Contains>::type {};
template struct Contains : false_type {};
// 獲取類型索引
template struct IndexOf;
template
struct IndexOf { enum { value = 1 + IndexOf::value }; };
template
struct IndexOf { enum { value = 0 }; };
template struct IndexOf { enum { value = -1 }; };
tuple 本身是可變模板參數類型,可用於存儲參數包、實現編譯期遍歷/查找/合並。常見技巧:生成索引序列 IndexSeq,配合 std::get 將 tuple 還原為參數包。
template struct IndexSeq {};
template struct MakeIndexes : MakeIndexes {};
template struct MakeIndexes<0, Is...> { using type = IndexSeq; };
template
void printArgs(Args... args) {
printHelper(typename MakeIndexes::type(), make_tuple(args...));
}
template
void printHelper(IndexSeq, tuple&& tup) {
print(get(tup)...);
}
template void print(T t) { cout << t << '\n'; }
template void print(T t, Args... args) { print(t); print(args...); }
aligned_storage 作為緩衝區,placement new 構造對象,type_index 記錄當前類型,內置 Visit 以 lambda 方式訪問值。C++11 將模板元編程從「黑魔法」推向實用工程:type_traits 提供豐富元函數庫,可變模板實現參數包算法,tuple 連接運行期與編譯期。掌握「類型重定義、遞歸展開、偏特化、SFINAE」四大核心技巧,配合標準庫設施,即可編寫高效、類型安全的泛型代碼。