模版元编程学习笔记
以前常听说递归展开,最近学习了模版元编程才明白是怎么回事,下面让我慢慢道来。
模版元编程,就是把运行期作的事情放到编译期去做,特点是:
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
template <int n>3
struct a4
{5
enum6
{7
result= n*a<n-1>::result,8
};9
};10

11

12
template <>13
struct a<0>14
{15
enum16
{17
result= 1,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
};
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>::result7
: 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
};上面这段程序使用了?: 运算符,: 两侧的表达式无论计算与否,都会在编译期展开。这里显然是需要优化的,优化的结果是只展开我们需要的那个分支,加快编译速度。下面是优化后的解决方案。
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
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> >::ResultT31
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

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


浙公网安备 33010602011771号