新余公司做网站,公司和个人均不能备案论坛类网站,flipaclip动画制作,专利交易网站建设ppt1. 推荐书籍
《C新经典 模板与泛型编程》难得的很容易看得懂的好书#xff0c;作者讲技术不跳跃#xff0c;娓娓道来#xff0c;只要花点时间就能看懂。
2. 笔记
2.1 模板基础
模板为什么要用尖括号#xff1f;因为便于编译器解析#xff0c;可以将模板和普通函数声明…1. 推荐书籍
《C新经典 模板与泛型编程》难得的很容易看得懂的好书作者讲技术不跳跃娓娓道来只要花点时间就能看懂。
2. 笔记
2.1 模板基础
模板为什么要用尖括号因为便于编译器解析可以将模板和普通函数声明分开。其实尖括号就相当于函数声明中用于把参数包裹起来的圆括号其中参数就是传入的类型模板参数。如
template typename T // 尖括号相当于函数的圆括号T相当于函数的形参
class A {}当然模板支持传递的参数种类不止一种有类型模板参数非类型模板参数模板模板参数。其实对于没有学习过模板的同学来说这几种类型即使说了也看不懂。就像某些教材一样只负责陈述不负责让你看懂。上面说的内容在书中的前几章有很多例子一看就懂。
综上可以认为模板就是一个编译期的代码生成函数这个函数最原始的用途是在编译器解析后生成实例化后的代码。后面发现模板竟然支持编译期的分支判断和循环控制支持对代码生成过程增加更加精细和复杂的控制。逐步发展成了元编程简单来说就是编译期编程。
2.2 模板特化
一直搞不懂偏特化的模板怎么写怎么推导。直到看到了《C新经典 模板与泛型编程》的第5.1.3节如以下
// 泛化版本 先写好泛化模板
template typename T
class A {}// 偏特化版本
template typename T // 最后写这里声明一个泛化类型参数
class AT * // 因为泛化模板需要一个类型参数特化版本需要调用泛化版本。所以这里需要传入一个类型这里假设是T *T是一个模板参数需要在使用模板类A的时候指定。
{}模板的特化版本必须调用泛化版本。而且特化版本不能单独存在必须先写出泛化版本的模板。综上可以理解为特化版本是对泛化版本的一次编译期的“函数”封装因为有一个调用的过程所以这里我称之为函数封装。正因为是函数封装在调用泛化模板时需要保持参数数量相同。综上模板写起来有很多限制语法不是那么随意这样的好处是便于编译器解析。
2.3 总体把握模板技术 整个C模板与泛型系统的底层逻辑是调用模板通过实参确定类型根据特化情况调用匹配的模板函数推导和展开其他类型直到无法继续展开。其中类型匹配机制实现了编译期的分支控制递归调用模板实现了循环控制两种机制统称为编译器类型推导。二者结合几乎所有的逻辑都可以实现。 常见的模板类型有函数模板类模板变量模板别名模板。 只有函数模板在使用的时候可以不指定模板参数编译器会自动推导只需要指定函数实参即可。这就是为什么有时候模板不需要传一个用尖括号包起来的类型参数的原因。其他模板在使用的时候需要指定模板参数也就是类型模板参数。 模板的优点是编译期执行一些编译期间能够确定的逻辑提高执行效率省去一些动态类型转换与判断造成的性能损耗。如果一些信息不能在编译期确定只能在运行期间确定那这种情况下模板就发挥不了作用。模板还可以提高代码复用性总体来说模板是和代码架构相关的技术一般需要花精力好好设计的可复用模块才可能需要使用模板。任何技术都有它的应用场景实事求是因地制宜才是少走弯路的方法。 编写模板要大胆的写编译器能解析的模板就是正确的模板。一般来说只要是能推导的都能编译通过。模板的语法可以在尝试中探索和掌握。 总体来说编译期的泛型编程和C/C逻辑基本上是一致的只是泛型编程的核心是类型类型就是泛型编程中的变量。一定要掌握核心逻辑才能学的轻松。
2.4 万能引用
万能引用只有两种使用场景一是函数模板与完美转发二是 auto 。 目前C中一共有三种引用左值引用右值引用万能引用。一句话理解万能引用只要你用了万能引用编译器就会向上找这个引用最原始的来源从而确定这个万能引用到底是左值引用来使用还是作为右值引用来使用。专业术语叫引用折叠不理解的话是真的不好懂。
2.5 萃取
萃取就是由类型匹配机制推导出另外一种类型或者推导出一个值前者叫类型萃取后者叫值萃取。当然要看书中的例子不然这句话肯定是无法理解的。萃取实际上就是分支判断。利用萃取中的SFINAE就可以编写很多编译期的判断函数模板、判断类模板一起组成编译期函数库用来实现更加复杂的模板逻辑。
2.6 高大上词汇 显式具体化就是全特化因为全特化后的模板不需要推导它就是一个实实在在可以被编译到cpp中的函数或类或变量。它的声明需要被写到头文件中实现需要被写到cpp中如果写在头文件中可能会出现重定义错误。 显式实例化就是给某个模板传递好类型参数一旦类型确定模板就被实例化成可以被编译到cpp中的函数或类或变量。显示具体化和显式实例化本质上是一样的显式具体化是通过全特化写法实现的显式实例化是通过传递具体的类型参数将模板实例化得到的。显式实例化只需要写到cpp中。 隐式实例化在模板使用的时候传递确定的类型参数这个时候编译器会自动生成代码不需要开发者参与所以叫隐式实例化。
2.7 元编程
类模板函数模板等都是元编程。
需要特别注意的元函数是通过递归的方式生成内联代码的元函数。
通过递归生成代码机制可以实现变长的类型列表typelist变长的多类型容器tuple。这个太绕暂时知道即可需要用的时候再仔细研究吧。
2.8 标准模板库的实现原理
一般开发中我们是学者怎么用标准模板库写业务代码而比较少能看懂标准模板库的代码书中这一块有具体讲解可以当作闲暇读物。 入门篇完结。