C++模板

很久没有看过C++模板,因为日常用不到。以前看书的东西已经忘记了。写此文方便自己抓住要点,快速开窍。

模板就是模板,它并不是某种的原始类型。如果把模板当成一个类型,在错误的概念下就会有很多奇怪的矛盾,不合理的地方。

恰如其名:编译器使用模板,通过更换模板参数来创建数据类型。这个过程就是模板实例化(Instantiation)。从模板类创建得到的类型称之为特例(specialization)。模板实例化取决于编译器能够找到可用代码来创建特例(称之为实例化要素,point of instantiation)。要创建特例,编译器不但要看到模板的声明,还要看到模板的定义。模板实例化过程是迟钝的,即只能用函数的定义来实现实例化。

理解了这一点,就基本理解了模板的本质。这也体现了2-level langurage的特点。这也是叫做:图灵完备的函数式编程的原因。

为了实例化,模板编译器很智能,必须能够推导,其核心就是推导出该有的类型。

2. 最初的确是类型泛型引入的,然后要支持3类模板参数:

1. type 2. non-type 2.template arg

然后要推导类型,就发现支持了分支与循环。差不多就图灵完备了。

举个例子:

#include <iostream>
template<int N>class sumt{public: static const int ret = sumt<N-1>::ret + N;};template<>class sumt<0>{public: static const int ret = 0;};
int main() { std::cout << sumt<5>::ret << '\n'; std::cin.get(); return 0;}

sumt<5>是一个实例化类型,

然后生成了sumt<4>,sumt<3>...sumt<0>

 C++ 模板是图灵完备的,这使得 C++ 成为两层次语言(two-level languages,中文暂且这么翻译,文献[9]),其中,执行编译计算的代码称为静态代码(static code),执行运行期计算的代码称为动态代码(dynamic code),C++ 的静态代码由模板实现(预处理的宏也算是能进行部分静态计算吧,也就是能进行部分元编程,称为宏元编程,见 Boost 元编程库即 BCCL,文献[16]和文献[1] 10.4)。

具体来说 C++ 模板可以做以下事情:编译期数值计算、类型计算、代码计算(如循环展开),其中数值计算实际不太有意义,而类型计算和代码计算可以使得代码更加通用,更加易用,性能更好(也更难阅读,更难调试,有时也会有代码膨胀问题)。编译期计算在编译过程中的位置请见下图(取自文献[10]),可以看到关键是模板的机制在编译具体代码(模板实例)前执行:

从编程范型(programming paradigm)上来说,C++ 模板是函数式编程(functional programming),它的主要特点是:函数调用不产生任何副作用(没有可变的存储),用递归形式实现循环结构的功能。C++ 模板的特例化提供了条件判断能力,而模板递归嵌套提供了循环的能力,这两点使得其具有和普通语言一样通用的能力(图灵完备性)。

编程形式来看,模板的“<>”中的模板参数相当于函数调用的输入参数,模板中的 typedef 或 static const 或 enum 定义函数返回值(类型或数值,数值仅支持整型,如果需要可以通过编码计算浮点数),代码计算是通过类型计算进而选择类型的函数实现的(C++ 属于静态类型语言,编译器对类型的操控能力很强)

参考:

关于模板元编程,这是我见过最牛的文章了!-面包板社区

C++模板类之理解编译器的编译模板过程_君临丶天下的博客-CSDN博客

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值