C++模板学习之递归

C++中模板的推导是在编译期由编译器完成的,因此,可以利用模板将一些预先知道递归次数的递归算法用模板编程实现,以此实现将计算从运行期提前到编译期。利用模板完成递归算法与通常模式的递归算法一样,需要递归的公式和递归的结束条件。在模板元编程中,递归的公式利用模板参数的嵌套依赖来实现,而递归的结束条件利用特化模板参数来实现。比如求1到n的和,递归的公式为sum(n) = sum(n-1) + n,而递归的结束条件为sum(0)=0.于是,我们就可以写出如下的模板:

#include <iostream>

template <int N>
class Sum
{
public:
    enum {sum = Sum<N-1>::sum + N};
};

template <>
class Sum<0>
{
public:
    enum {sum = 0};
};

int main()
{
    std::cout << "sum of 1 to 100 is: " << Sum<100>::sum << std::endl;
    return 0;
}

可以看到,第一个类定义template <int N> class Sum就是定义了一个主模板类,用于递归公式的计算,而第二个模板类template<> class Sum<0>是一个特化的模板类,指明在N=0时模板类的行为。需要注意的是,特化模板类的定义必须在主模板类的后面。(如果类Sum<N>未定义,编译器又怎么会知道sum<0>是个什么东西呢?)

还有一点要注意的是,此处模板类中的成员sum我们使用了枚举类型,这是因为如果使用变量的话,它是不会去在编译期推导值的(C++类成员变量初始化不能放在类定义中),当然,使用static变量也是可以的。编译运行结果:

查看编译后的程序二进制代码可以发现,5050(二进制13BA)是直接以常数的形式编到main函数中的,也就是说,这个值是在编译期就已经由编译器算出来了的,这种情况下,运行时的计算时间就会大大减少。

时间: 2024-10-19 21:42:04

C++模板学习之递归的相关文章

算法学习笔记 递归之 快速幂、斐波那契矩阵加速

递归的定义 原文地址为:http://blog.csdn.net/thisinnocence 递归和迭代是编程中最为常用的基本技巧,而且递归常常比迭代更为简洁和强大.它的定义就是:直接或间接调用自身.经典问题有:幂运算.阶乘.组合数.斐波那契数列.汉诺塔等.其算法思想: 原问题可分解子问题(必要条件): 原与分解后的子问题相似(递归方程): 分解次数有限(子问题有穷): 最终问题可直接解决(递归边界): 对于递归的应用与优化,直接递归时要预估时空复杂度,以免出现用时过长或者栈溢出.优化递归就是以

学习了解递归和尾递归的区别

学习了递归和尾递归后,自己做了一些简单的总结,便于学习. 以典型的斐波那契数列为例,比较二者: import java.util.Scanner; public class testFibonacci { public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); System.out.println(fibonacci1(n)); System.out.pr

模板学习实践二 pointer

c++ template学习记录 使用模板将实际类型的指针进行封装 当变量退出作用域 自动delete // 1111.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" template <typename T> class Holder { private: T* ptr; // refers to the object it holds (if any) public: // default constructor: let the

c/c++ 斐波那契数列 利用模板元解决递归慢的问题

#include<iostream> //模板元 变成 一般用于递归 游戏开发里常用template<int N>struct data{ enum {res=data<N-1>::res+data<N-2>::res};};template<>struct data<1>{ enum {res=1};};template<>struct data<2>{ enum {res=2};}; int getdata

C++模板学习随笔

本文学习内容参考:http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html C++模板 1.模板分为函数模板和类模板两种类型 函数模板针对参数类型不同的函数: 类模板针对数据成员和成员函数类型不同的类: 使用模板的目的就是能够让程序员编写与类型无关的代码.比如编写了一个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的交换就要重新编写另一个swap函数.使用模

控件模板学习笔记(二)

1.模板绑定TemplateBinding 什么情况下使用模板绑定? --当您仍可能想要使用公共属性更改控件的外观时,模板绑定是您的不二之选 怎么使用模板绑定? --我们还以学习笔记一中的Button为例,自定义模板中的Border的Background=“Red”,使用TemplateBinding则为Background=“{TemplateBinding Backbround}”: 等号左边的Background为Border的背景颜色,等号右边的Background为Button的属性.

汇编语言学习系列 递归实现

假如汇编语言要实现如下C语言的功能,编译环境Ubuntu14.04(32位). #include<stdio.h> int refact(int n){ if(n == 1) return 1; else return n * refact(n - 1); } int main(){ int a = 4; printf("%d\n", refact(a)); return 0; } 无论对于递归实现还是循环实现,汇编都是将转换为跳转语句实现.可以把上面的代码转换为 refa

tornada模板学习笔记

import tornado.web import tornado.httpserver import tornado.ioloop import tornado.options import os.path from tornado.options import define, options define("port", default=8000, help="run on the given port", type=int) class HelloHandle

C++模板学习:函数模板、结构体模板、类模板

C++模板:函数.结构体.类 模板实现 1.前言:(知道有模板这回事的童鞋请忽视) 普通函数.函数重载.模板函数 认识. //学过c的童鞋们一定都写过函数sum吧,当时是这样写的: int sum(int a,int b) { return a+b; } //实现了整数的相加 //如果再想同时实现小数的相加,就再多写个小数的相加.普通实现我就不写了,知道函数重载的童鞋们会这样写: int sum(int a,int b) {//第一个function return a+b;} double su