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元编程是图灵完备的,也就是说,任何程序中需要表达的计算,都可以采用这种方式表达。

  • 相关阅读:
    1046 Shortest Distance (20 分)(模拟)
    1004. Counting Leaves (30)PAT甲级真题(bfs,dfs,树的遍历,层序遍历)
    1041 Be Unique (20 分)(hash散列)
    1036 Boys vs Girls (25 分)(查找元素)
    1035 Password (20 分)(字符串处理)
    1044 Shopping in Mars (25 分)(二分查找)
    onenote使用小Tip总结^_^(不断更新中...)
    1048 Find Coins (25 分)(hash)
    三个故事
    领导者的举止
  • 原文地址:https://www.cnblogs.com/cknightx/p/7821068.html
Copyright © 2011-2022 走看看