一:概念:
在 C++ 中,递归模板是一种编程技术,允许在编译期通过递归定义模板,生成复杂的类型或计算复杂的表达式。递归模板通常用于元编程,允许在编译期进行类型生成、计算等操作,避免运行时开销。递归模板广泛应用于编译期常量计算、类型列表操作、类型萃取等场景。
二:原理:
递归模板的实现分为两个部分:
- 递归模板定义:定义一个模板,并在其中递归调用自身,直到满足某个条件。
- 基例特化(终止条件):在模板递归的末尾定义基例(base case),即递归的终止条件。
三: 示例(编译期计算):
#include <iostream>
// 递归模板计算阶乘
template <int N>
struct Factorial {
static const int value = N * Factorial<N - 1>::value;
};
// 基例:0 的阶乘是 1
template <>
struct Factorial<0> {
static const int value = 1;
};
int main() {
std::cout << "Factorial<5>::value = " << Factorial<5>::value << std::endl; // 输出 120
return 0;
}
#include <iostream>
template <int N>
struct Sum {
static const int value = N + Sum<N - 1>::value;
};
// 基例:Sum<0> 为 0
template <>
struct Sum<0> {
static const int value = 0;
};
int main() {
std::cout << "Sum<5>::value = " << Sum<5>::value << std::endl; // 输出 15
return 0;
}
#include <iostream>
int power(int m, int n){
int r = 1;
for(int k=1; k<=n; ++k) r*= m;
return r;
}
template<int m, int n>
struct Power{
static const int value = Power<m,n-1>::value * m;
};
template<int m>
struct Power<m,0>{
static const int value = 1;
};
template<int n>
int power(int m){
return power<n-1>(m) * m;
}
template<>
int power<0>(int){
return 1;
}
int main(){
std::cout << '\n';
std::cout << "power(2,10): " << power(2,10) << '\n';
std::cout << "power<10>(2): " << power<10>(2) << '\n';
std::cout << "Power<2,10>::value: " << Power<2,10>::value << '\n';
std::cout << '\n';
}
四:示例(类型列表 Type List):
#include <iostream>
#include <type_traits>
// 定义类型列表结构
template <typename... Ts>
struct TypeList {};
// 递归模板计算类型列表长度
template <typename List>
struct Length;
template <typename Head, typename... Tail>
struct Length<TypeList<Head, Tail...>> {
static const int value = 1 + Length<TypeList<Tail...>>::value;
};
// 基例:空列表的长度为 0
template <>
struct Length<TypeList<>> {
static const int value = 0;
};
int main() {
using MyTypes = TypeList<int, double, float, char>;
std::cout << "Length of MyTypes = " << Length<MyTypes>::value << std::endl; // 输出 4
return 0;
}
五:示例(类型萃取) :
#include <iostream>
#include <type_traits>
// 定义类型列表
template <typename... Ts>
struct TypeList {};
// 递归模板检查是否包含某个类型
template <typename T, typename List>
struct Contains;
// 递归定义:检查类型
template <typename T, typename Head, typename... Tail>
struct Contains<T, TypeList<Head, Tail...>> {
static const bool value = std::is_same<T, Head>::value || Contains<T, TypeList<Tail...>>::value;
};
// 基例:空列表返回 false
template <typename T>
struct Contains<T, TypeList<>> {
static const bool value = false;
};
int main() {
using MyTypes = TypeList<int, double, float, char>;
std::cout << "Does MyTypes contain int? " << (Contains<int, MyTypes>::value ? "Yes" : "No") << std::endl; // 输出 Yes
std::cout << "Does MyTypes contain long? " << (Contains<long, MyTypes>::value ? "Yes" : "No") << std::endl; // 输出 No
return 0;
}