免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1846 | 回复: 6
打印 上一主题 下一主题

这段代码的原理是什么 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-15 22:50 |只看该作者 |倒序浏览
#include <iostream>

template<int N>
struct sum {
    enum {result = sum<N-1>::result + N };
};

template<>
struct sum<1> {
   enum{result = 1};
};


int main (int argc, char *argv[]) {
    std::cout << sum<10>::result << std::endl;
    return 0;
}

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
2 [报告]
发表于 2009-07-16 00:50 |只看该作者

回复 #1 apple753357 的帖子

编译器遇见:
std::cout << sum<10>::result << std::endl;

中的sum<10>,就会去实例化这个类模板。

由类模板定义:
enum {result = sum<N-1>::result + N };
sum<10> 又会实例化sum<9>

sum<9> 会继续实例化sum<8>

直到sum<2>
enum { result = sum<1>::result + 2 };

而sum<1>有偏特化版本:
template<>
struct sum<1> {
   enum{result = 1};
};

递归终止,得到结果sum<10>::result = 55;

论坛徽章:
0
3 [报告]
发表于 2009-07-16 10:39 |只看该作者
就是在编译阶段实现递归。

论坛徽章:
0
4 [报告]
发表于 2009-07-17 00:32 |只看该作者
这种依赖编译期的c++代码编写方式有什么用吗?

论坛徽章:
80
20周年集字徽章-庆
日期:2020-10-28 14:09:1215-16赛季CBA联赛之北京
日期:2020-10-28 13:32:5315-16赛季CBA联赛之北控
日期:2020-10-28 13:32:4815-16赛季CBA联赛之天津
日期:2020-10-28 13:13:35黑曼巴
日期:2020-10-28 12:29:1520周年集字徽章-周	
日期:2020-10-31 15:10:0720周年集字徽章-20	
日期:2020-10-31 15:10:07ChinaUnix元老
日期:2015-09-29 11:56:3020周年集字徽章-年
日期:2020-10-28 14:14:56
5 [报告]
发表于 2009-07-17 07:56 |只看该作者
学习

论坛徽章:
0
6 [报告]
发表于 2009-07-17 13:25 |只看该作者
学习一下,还没这么用过

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
7 [报告]
发表于 2009-07-17 14:42 |只看该作者

回复 #5 apple753357 的帖子

原帖由 apple753357 于 2009-7-17 00:32 发表
这种依赖编译期的c++代码编写方式有什么用吗?


这种用法有时候被称为模板元编程(template meta programming)。
利用编译器对模板实例化进行编程工作, 编程的结果本身就作为另一个程序。

例子嘛……  比如一个题目, 解析完题意就是,输入n ( 1 <= n <= 10 ),输出 n!。

按照常规也可以运行时计算:

---- factorial.cpp ----

int factorial(int n) { ... }

int main(void) {
    int n = 0;
    scanf("%d",&n);
    printf("%d\n",factorial(n));
}


要更快一点么,  显然就是做一个表, 直接查:

---- factorial.cpp ----
static const int factorials[]  = {
   // 这里怎么计算表?
};

int main(void) {
    int n = 0;
    scanf("%d",&n);
    printf("%d\n",factorials[n] );
}


表的计算那里可以用计算器算出来, 然后填……

也可以由另外一个程序生成:
---- generating.cpp ----
int main(void) {    for (int i=0,j=1;i<=10,++i,j*=i) printf("    %d,\n",j); }

generating.exe > 1.txt
然后复制到factorial.cpp中, factorial.cpp 再编译为程序。

而模板元编程可以直接在一个cpp中完成这个事情。

template<int n>
struct factorial { enum { value = factorial<n-1>::value * n }; };

template<>
struct factorial<0> { enum { value=1 }; };

static const int factorials[] = {
    factorial<0>::value,
    factorial<1>::value,
    // ...
    factorial<10>::value,
};

[ 本帖最后由 OwnWaterloo 于 2009-7-17 14:45 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP