我的C++实践(7):模板元编程实战

    (1)计算整数的幂。

    Pow<N,M>用来计算N的M次幂。实例化层次是Pow<N,M>,Pow<N,M-1>,...,Pow<N,0>,共M+1层。我们始终要记住编译器对模板元编程中的实例化层次是有限制的(否则会层次太深的话会耗尽编译器的可用资源),我测试出gcc 4.2.4最多只允许31层的实例化,因此这里如果使用Pow<2,31>,Pow<5,40>等,则编译不会通过。
    (2)求整数的平方根(向上取整)。可以用二分查找算法来查找,也可以用普通的从0开始迭代的查找算法。

    在模板元编程中,我们要尽量少用条件运算符?:来执行路径选择,因为这会导致两个分支中的递归模板都会被实例化,产生数量庞大的实例化体。例如使用sqrt1.hpp中注释掉的那句,当实例化Sqrt<N,LO,HI>时,会导致Sqrt<N,LO,mid-1>和Sqrt<N,mid,HI>的完全实例,这样最终的实例化个数大约是N的2倍。我们应该用模板特化来执行路径选择,例如我们使用前面类型萃取技术中介绍的IfThenElse<bool,T1,T2>模板。在它的特化中ResultT只返回其中一个类型(如T1),注意把T1类型typedef成ResultT并不会导致被实例化。当最终查找结果ResultT::resut时,就会实例化ResultT,可见这只实例化了一个IfThenElse中的一个分支。最终的实例化个数趋向于lg(N)。另外,在二分查找的实现中,返回是其中的一个分支类型,最后返回时应该是mid=HI时的Sqrt<N,mid,HI>,因此必须提供一个mid=HI的特化来结束Sqrt模板的递归,否则还会再去实例化Sqrt<N,mid,HI>。而在迭代查找的实现中,当I*I>=N时模板递归结束,这时返回Value<I>分支,用Value<I>::result直接返回计算出的结果,递归结束。因此不需要提供Sqrt的特化来结束递归。

    (3)计算向量的点乘。

    (4)判断一个数是否是素数。

    (5)打印连续的素数。

    总结出模板元编程的计算完整性:
    1)状态变量:也就是模板参数
    2)迭代构造(相当于循环语句):通过递归模板
    3)路径选择(相当于条件语句):通过使用特化或条件表达式?:
    4)整型对象(相当于变量):用enum定义的枚举值

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值