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;
}
}