C++ 模板专题 - 递归模板

一:概念:

     在 C++ 中,递归模板是一种编程技术,允许在编译期通过递归定义模板,生成复杂的类型或计算复杂的表达式。递归模板通常用于元编程,允许在编译期进行类型生成、计算等操作,避免运行时开销。递归模板广泛应用于编译期常量计算、类型列表操作、类型萃取等场景。   

二:原理:      

递归模板的实现分为两个部分:

  1. 递归模板定义:定义一个模板,并在其中递归调用自身,直到满足某个条件。
  2. 基例特化(终止条件):在模板递归的末尾定义基例(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;
}

猜你喜欢

转载自blog.csdn.net/zg260/article/details/143377033