C++ 模板元编程语法大全
模板元编程(Template Metaprogramming, TMP)是C++中利用模板在编译期进行计算和代码生成的强大技术。以下是C++模板元编程的核心语法和概念总结:
1. 基础模板语法
类模板
template <typename T>
class MyClass {
// 类定义
};
函数模板
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
非类型模板参数
template <typename T, int N>
class Array {
T data[N];
// ...
};
2. 模板特化
全特化
template <>
class MyClass<int> {
// 针对int类型的特化实现
};
偏特化
template <typename T>
class MyClass<T*> {
// 针对指针类型的偏特化
};
3. 可变参数模板
template <typename... Args>
void print(Args... args);
// 递归展开
template <typename T, typename... Rest>
void print(T first, Rest... rest) {
std::cout << first << " ";
print(rest...);
}
// 终止条件
void print() {}
4. SFINAE (Substitution Failure Is Not An Error)
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
foo(T t) {
// 仅对整数类型有效
return t;
}
5. 类型萃取 (Type Traits)
#include <type_traits>
// 检查类型是否是整数
static_assert(std::is_integral<int>::value, "int is integral");
// 移除const限定符
std::remove_const<const int>::type; // int
6. 编译期计算
编译期阶乘
template <int N>
struct Factorial {
static const int value = N * Factorial<N-1>::value;
};
template <>
struct Factorial<0> {
static const int value = 1;
};
constexpr int fact5 = Factorial<5>::value; // 120
constexpr函数 (C++11起)
constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n-1);
}
constexpr int fact5 = factorial(5); // 120
7. 模板元编程常用技巧
条件选择
template <bool B, typename T, typename F>
using Conditional = typename std::conditional<B, T, F>::type;
编译期判断
template <typename T1, typename T2>
struct IsSame {
static const bool value = false;
};
template <typename T>
struct IsSame<T, T> {
static const bool value = true;
};
类型列表操作
template <typename... Ts>
struct TypeList {};
// 获取第一个类型
template <typename List>
struct Front;
template <typename Head, typename... Tail>
struct Front<TypeList<Head, Tail...>> {
using type = Head;
};
8. C++17及以后的新特性
if constexpr
template <typename T>
auto get_value(T t) {
if constexpr (std::is_pointer_v<T>) {
return *t;
} else {
return t;
}
}
折叠表达式
template <typename... Args>
auto sum(Args... args) {
return (args + ...); // 折叠表达式
}
概念(Concepts) (C++20)
template <typename T>
concept Integral = std::is_integral_v<T>;
template <Integral T>
T add(T a, T b) {
return a + b;
}
9. 模板元编程实用工具
编译期字符串
template <char... Chars>
struct FixedString {
static constexpr char value[] = {Chars..., '\0'};
};
编译期数组
template <typename T, T... Values>
struct ValueList {
static constexpr T array[] = {Values...};
};
10. 高级技巧
CRTP (奇异递归模板模式)
template <typename Derived>
class Base {
void interface() {
static_cast<Derived*>(this)->implementation();
}
};
class Derived : public Base<Derived> {
void implementation();
};
表达式模板
template <typename L, typename R>
struct AddExpr {
L const& lhs;
R const& rhs;
auto operator[](size_t i) const { return lhs[i] + rhs[i]; }
};
template <typename E>
class Vec {
// 通过表达式模板实现延迟计算
};
模板元编程是C++中最复杂的特性之一,但它提供了强大的编译期计算和代码生成能力。随着C++标准的演进,模板元编程的语法和功能也在不断丰富和完善。