metaprogram(编译器求值)

1、通过模板技术,可以在编译期进行一些操作求值,利用的原理是模板实例化,递归的技术

如需要求某个数的平方根,一般情况下使用如下接口

for(int i = 0; i*i < N; ++i)

{

;

}

// 最后i即N的平方根

通过模板技术

template<int N,int i =0>

class sqrt

{

public;

enum

{

result = (i * i < N) ? Sqrt<N, i+1>::result : i;

}

}

最后返回的i就是需要的平方根了,而且这个在编译器就执行出结果了

2、但是上面例子中编译会失败,会让编译器异常。

原因如下:

执行到i=2时

result = (2 * 2 < 4) ? Sqrt<4, 3>::result, : 2;

虽然返回结果为2了,但是Sqrt<4,3>依旧会被实例化,会继续执行,依次类推,会一直执行下去


解决方案:

增加一个特例化模板

template<int N>

class Sqrt<N, N>

{

public:

enum

{

result = N;

}

}

这样执行到Sqrt<4, 4>时,就会到上面这个特例化例子中,编译器也就结束了

3、上面例子依旧有个问题,这样会导致编译器多实例化很多例子,如何解决这个问题呢?引入了另外一个模板

template<bool C, typename Ta, typename Tb>

class IfThenElse;

// 实例化1

template<typename Ta, typename Tb>

class IfThenElse<true, typename Ta, typename Tb>

{

public:

typedef Ta ResulT;

};

// 实例化2

template<typename Ta, typename Tb>

class IfThenElse<true, typename Ta, typename Tb>

{

public:

typedef Tb ResulT;

};

另外增加一个额外的类

template<typename T>

class Value

{

public:

enum 

{

result = N

}

}

求平方根进行改写

template<int N,int i =0>

class sqrt

{

public;

typedef typename IfThenElse<i*i<N, Sqrt<T,i+1>,Value<T>>::Result SubT;

enum

{

result = SubT::result;

}

}


你可能感兴趣的:(metaprogram(编译器求值))