模版元编程学习笔记
以前常听说递归展开,最近学习了模版元编程才明白是怎么回事,下面让我慢慢道来。
模版元编程,就是把运行期作的事情放到编译期去做,特点是:
1。代码短小精悍。
2。效率通常都比较高。
3。可维护性好。
4。实现编译期错误检查。
请看一个递归展开的例子:
1
2
template <int n>
3
struct a
4
{
5
enum
6
{
7
result= n*a<n-1>::result,
8
};
9
};
10
11
12
template <>
13
struct a<0>
14
{
15
enum
16
{
17
result= 1,
18
};
19
};
20

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

这个例子基本和非模版版本实现是一样的,都是通过递归处理,然后当递归到达终点的时候跳出(在这里是通过模版特化实现)。区别是这里的递归展开是在编译期进行的!!多么奇妙的事情,这意味者虽然增加了编译时间,但运行期速度是非常快的。
让我们继续看一个计算平方根的程序(来自 c++ template)。
1
template <int N, int LO=1, int HI=N>
2
class Sqrt {
3
public:
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
10
template<int N, int M>
11
class Sqrt<N,M,M>
12
{
13
public:
14
enum { result = M };
15
};

2

3

4

5

6

7

8

9

10

11

12

13

14

15

上面这段程序使用了?: 运算符,: 两侧的表达式无论计算与否,都会在编译期展开。这里显然是需要优化的,优化的结果是只展开我们需要的那个分支,加快编译速度。下面是优化后的解决方案。
1
template<bool C, typename Ta, typename Tb>
2
class IfThenElse;
3
4
template<typename Ta, typename Tb>
5
class IfThenElse<true, Ta, Tb>
6
{
7
public:
8
typedef Ta ResultT;
9
};
10
11
template<typename Ta, typename Tb>
12
class IfThenElse<false, Ta, Tb>
13
{
14
public:
15
typedef Tb ResultT;
16
};
17
18
19
//------------------------------------------------------------------
20
21
22
template<int N, int LO=1, int HI=N>
23
class Sqrt
24
{
25
public:
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
35
template<int N, int S>
36
class Sqrt<N, S, S>
37
{
38
public:
39
enum { result = S };
40
};
41

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

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