zoukankan      html  css  js  c++  java
  • 初探模板元编程

    来看一个小例子:

    #include<iostream>
    template<long num>
    struct Fibonacci
    {
    	static const long val = Fibonacci<num - 1>::val + Fibonacci<num - 2>::val;
    };
    
    template<> struct Fibonacci<2> { static const long val = 1; };
    template<> struct Fibonacci<1> { static const long val = 1; };
    template<> struct Fibonacci<0> { static const long val = 0; };
    
    int main()
    {
    	int i=Fibonacci<10>::val
    	std::cout<<i;
    }
    

    上面程序的输出结果正是斐波那契数列第11个项。与通常的程序不同之处在于,它的结果是在编译时计算出来的。对此我们可以查看反汇编:

    可见运行时直接使用的是37h即55这个值。

    下面我们来分析一下。
    首先定义了一个非类型参数的模板Fibonacci,该模板类定义了一个静态变量val,而val被递归地定义为特化num=num-1和num-2的类中val之和。
    所以,val = Fibonacci<num - 1>::val + Fibonacci<num - 2>::val
    Fibonacci<num - 1>::val又被递归定义为val = Fibonacci<num - 2>::val + Fibonacci<num - 3>::val,同理Fibonacci<num - 2>::val被递归定义为Fibonacci<num - 3>::val+Fibonacci<num - 4>::val
    既然是递归,就必须有边界条件作为递归的终点。
    所以我们特化当num=0,1,2时val的值为确定的0,1,1。

    template<> struct Fibonacci<2> { static const long val = 1; };
    template<> struct Fibonacci<1> { static const long val = 1; };
    template<> struct Fibonacci<0> { static const long val = 0; };
    

    因为模板是在编译时被推导展开的,所以Fibonacci数列的值也就在编译时被计算出来了。

    再举一个阶乘的小例子:

    #include<iostream>
    template<long num>
    struct Factorial
    {
    	static const long val = num*Factorial<num - 1>::val;
    };
    
    template<> struct Factorial<1> { static const long val = 1; };
    
    int main()
    {
    	int fib = Factorial<10>::val;
    	std::cout << fib;
    }
    

    思路完全相同,这里就不再赘述。

    ps:template元编程是图灵完备的,也就是说,任何程序中需要表达的计算,都可以采用这种方式表达。

  • 相关阅读:
    scala 数据结构(七 ):集 Set
    scala 数据结构(六):映射 Map
    scala 数据结构(五):队列 Queue
    scala 数据结构(四):列表 List
    scala 数据结构(三):元组Tuple
    scala 数据结构(二):数组
    scala 数据结构(一):数据结构简介
    Scala 面向对象(十三):隐式转换和隐式参数
    vba报表制作
    Apache与Nginx
  • 原文地址:https://www.cnblogs.com/cknightx/p/7821068.html
Copyright © 2011-2022 走看看