模板元编程入门
编译期计算 factorial、SFINAE、enable_if、类型萃取 traits
模板元编程入门
模板不只是泛型——它可以在编译期做计算。这就是模板元编程(TMP),让代码在编译时就确定结果。
学完本章你将: 掌握编译期 factorial、SFINAE、enable_if、类型萃取。
编译期计算
cpp
// 编译期阶乘——递归模板
template <int N>
struct Factorial {
static constexpr int value = N * Factorial<N - 1>::value;
};
template <>
struct Factorial<0> {
static constexpr int value = 1;
};
constexpr int result = Factorial<5>::value; // 120——编译时算出
int arr[result]; // 合法的数组大小!
SFINAE —— 替换失败不是错误
cpp
// 只有 T 有 toString() 方法时才启用这个重载
template <typename T>
auto print(const T& obj) -> decltype(obj.toString(), void()) {
std::cout << obj.toString() << "\n";
}
template <typename T>
void print(const T& obj) {
std::cout << obj << "\n"; // 回退到 << 输出
}
enable_if
cpp
// 只接受整数类型的函数
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
add(T a, T b) {
return a + b;
}
// C++14 简写
template <typename T>
std::enable_if_t<std::is_integral_v<T>, T> add(T a, T b) { return a + b; }
add(1, 2); // ✅ int——整数
// add(1.5, 2.5); // ❌ 编译错误——不是整数
类型萃取 traits
cpp
std::is_integral_v<int> // true
std::is_floating_point_v<double> // true
std::is_same_v<int, long> // false
std::is_base_of_v<Base, Derived> // true
std::remove_reference_t<int&> // int
std::decay_t<const int&> // int