编程文汇

[c++]模板特化与模板递归

cxx
#1

Hello World

//比如计算斐波那契数列
template<int n>
struct Factorial{
	const static int value=Factorial<n-1>::value*n;
};
//特化终结递归,否则上面那个递归会死循环,编译时报错
template<>
struct Factorial<0>{
	const static int value=1;
};

遍历查找变长模板包中的类型

//再比如,查找Args...泛型参数的位置,
//这个例子很有意思,能把Args...一层一层拆解,很暴力,脱!!
template <int Index, class Search, class First, class... Types>
struct get_internal {
  typedef typename get_internal<Index + 1, Search, Types...>::type type;
  static constexpr int index = Index;
};

template <int Index, class Search, class... Types>
struct get_internal<Index, Search, Search, Types...> {
  typedef get_internal type;
  static constexpr int index = Index;
};

template <class T, class... Types> T get(std::tuple<Types...> tuple) {
  return std::get<get_internal<0, T, Types...>::type::index>(tuple);
}

模板函数递归特化

//计算和。
//这种方法很有用,比如,
//在我的ECS中,我就用这种方式提前枚举出来所有System,自动创建对象,放入集合,供ECS调用。
template<typename T>
T adder(T v) {
  return v;
}

template<typename T, typename... Args>
T adder(T first, Args... args) {
  return first + adder(args...);
}

long sum = adder(1, 2, 3, 8, 7);

std::string s1 = "x", s2 = "aa", s3 = "bb", s4 = "yy";
std::string ssum = adder(s1, s2, s3, s4);

模板函数递归特化:利用辅助函数

  //这是对上一种情况的延申,因为这里只有模板参数,没有函数参数,
  //所以不能用参数来做特化,所以利用了一个辅助变量,曲线救国。
  template <class... T> void InitSystems() { InitSystemsHelper<T...>(); }
  template <> void InitSystems() {}
  template <class First, class... T> void InitSystemsHelper() {
    //do something to First
    InitSystems<T...>();
  }

函数编程

一切都要从函数的角度考虑,和OOP的思维方式真的不一样,也许,这就是大家感觉难的原因,思维方式一下转不过来。最后一种情况,我也是扭了半天,才把思维扭过来。

觉得还是值得的,可以部分让代码自动化。就跟在java里利用反射一样,只不这东西实在编译时进行,而且没有java那样直接了当。

也许这玩意就是所谓的元编程,可是,除了生成代码,别的场合我真不愿意用这种计算。

0 Likes