Z
ZHANK
编程在线教程C++ 教程模板元编程入门
并发与模板进阶

模板元编程入门

编译期计算 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