模板元编程 
简要介绍 
模板: 
是C++提供的一种泛型编程工具,可以让函数和类在编译时根据类型参数进行实例化。
模板元编程: 
核心思想是将计算推迟到编译时,利用模板递归、特化和偏特化等机制,进行类型推导、编译期计算和代码生成。这样可以减少运行时开销。
基本技巧: 
类型特化:根据不同类型提供不同的实现 
递归模板:通过模板的递归实例化,在编译期进行计算 
std::integral_constant:用于封装常量值,以便在编译时作为类型传递 
 
基本例子 
计算阶乘: 
通过模板递归,可以在编译期间计算出一个数的阶乘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include  <iostream>  template  <int  N>struct  Factorial  {static  const  int  value = N * Factorial<N - 1 >::value;template  <>struct  Factorial <0 > {static  const  int  value = 1 ;int  main ()  "Factorial of 5 is: "  << Factorial<5 >::value << std::endl;return  0 ;
编译时常量表达式: 
std::integral_constant是C++11引入的一个模板类,用于封装常量值,可以在编译时传递常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include  <iostream>  #include  <type_traits>  template  <typename  T>void  printType (T value)  if  (std::is_integral<T>::value) {"Integral type: "  << value << std::endl;else  {"Non-integral type: "  << value << std::endl;int  main ()  printType (42 );printType (3.14 );return  0 ;
类型选择: 
std::conditional是C++11引入的一个模板类,它根据条件选择两种类型中的一种
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include  <iostream>  #include  <type_traits>  template  <typename  T>void  printType (T value)  using  Type = typename  std::conditional<std::is_integral<T>::value, int , double >::type;static_cast <Type>(value);"Result: "  << result << std::endl;int  main ()  printType (42 );printType (3.14 );return  0 ;
模板特化: 
指的是对某个特定类型或特定类型组合提供模板的定制实现。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <iostream>  using  namespace  std;template  <typename  T>void  func (T t)  "Generic template: "  << t << endl;template  <>void  func <int >(int  t) {"Specialized template for int: "  << t << endl;int  main ()  func (10 ); func (3.14 ); 
模板偏特化: 
通常用于处理模板参数中的某些类型特征(比如说指针类型、数组类型等)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostrea>  using  namespace  std;template  <typename  T>void  func (T t)  "Generic template: "  << t << endl;template  <typename  T>void  func (T* t)  "Template specialized for pointer type: "  << *t << endl;int  main ()  int  a = 10 ;int * p = &a;func (a); func (p); 
函数重载与模板特化/偏特化的区别: 
函数重载:指的是为同一个函数名提供多个不同参数列表的实现。编译器根据传入参数的类型来选择合适的重载版本。函数重载是基于函数参数的类型和数量来选择执行哪个函数,而不涉及模板概念 
模板特化/偏特化:是针对模板的类型参数进行定制,根据传入的类型来选择对应的模板实例化。 
 
其他 
常用的模板元编程技巧: 
类型列表(Type List):一种用于存储多个类型的容器 
SFINAE(Substitution Failure Is Not An
Error):一种技巧,通过使模板在不适用时失败,从而为某些类型提供特化版本 
 
元编程工具: 
std::enable_if:条件启用模板功能的一种方法
std::is_same:判断两个类型是否相同
std::tuple:一个可以容纳多个不同类型的容器,类似于vector,但每个元素可以是不同的类型
std::index_sequence:生成从0到N的整数序列,通常用于编写递归和展开参数包