模版元编程学习笔记

   
    以前常听说递归展开,最近学习了模版元编程才明白是怎么回事,下面让我慢慢道来。

    模版元编程,就是把运行期作的事情放到编译期去做,特点是:
                1。代码短小精悍。
                2。效率通常都比较高。
                3。可维护性好。
                4。实现编译期错误检查。
      
   请看一个递归展开的例子:

 1
 2template <int n>
 3struct a
 4{
 5    enum
 6    {
 7        result= n*a<n-1>::result,
 8    }
;
 9}
;
10
11
12template <>
13struct a<0>
14{
15    enum
16    {
17        result= 1,
18    }
;
19}
;
20

        这个例子基本和非模版版本实现是一样的,都是通过递归处理,然后当递归到达终点的时候跳出(在这里是通过模版特化实现)。区别是这里的递归展开是在编译期进行的!!多么奇妙的事情,这意味者虽然增加了编译时间,但运行期速度是非常快的。


        让我们继续看一个计算平方根的程序(来自 c++ template)。


   
 1template <int N, int LO=1int HI=N>
 2class Sqrt {
 3public:
 4    enum { mid = (LO+HI+1)/2 };
 5
 6    enum { result = (N<mid*mid) ? Sqrt<N,LO,mid-1>::result
 7        : Sqrt<N,mid,HI>::result }
;
 8}
;
 9
10template<int N, int M>
11class Sqrt<N,M,M>
12{
13public:
14    enum { result = M };
15}
;


        上面这段程序使用了?: 运算符,: 两侧的表达式无论计算与否,都会在编译期展开。这里显然是需要优化的,优化的结果是只展开我们需要的那个分支,加快编译速度。下面是优化后的解决方案。


      
 1template<bool C, typename Ta, typename Tb>
 2class IfThenElse;
 3
 4template<typename Ta, typename Tb>
 5class IfThenElse<true, Ta, Tb>
 6{
 7public:
 8    typedef Ta ResultT;
 9}
;
10
11template<typename Ta, typename Tb>
12class IfThenElse<false, Ta, Tb> 
13{
14public:
15    typedef Tb ResultT;
16}
;
17
18
19//------------------------------------------------------------------
20
21
22template<int N, int LO=1int HI=N>
23class Sqrt 
24{
25public:
26    enum { mid = (LO+HI+1)/2 };
27
28    typedef typename IfThenElse<(N<mid*mid),
29        Sqrt<N,LO,mid-1>,
30        Sqrt<N,mid,HI> >::ResultT
31        SubT;
32    enum { result = SubT::result };
33}
;
34
35template<int N, int S>
36class Sqrt<N, S, S> 
37{
38public:
39    enum { result = S };
40}
;
41

   模版元编程是一部完整的图灵机,也就是说完备到能够计算任何事物。


posted on 2007-02-01 00:53  小峰  阅读(404)  评论(1)    收藏  举报

导航