这一章介绍了面向对象编程中最复杂的部分:模板与模板编程,读起来很吃力,总结也写了很久。其中16.2的类型转换部分会有点绕,16.4的可变参数模板则很实用,可以有效提高我们的开发效率。这篇内容较多较难,可以的话应该仔细看书慢慢看。
16.1.1 函数模板
-
上一章的OOP让我们可以在运行时处理运行前未知的动态情况,而泛型模板编程让我们可以在编译时就处理好一些动态的情况。在第二部分中介绍一些标准库容器时我们称其为泛型容器,因为它们可以利用了模板类的特性能对各种符合要求的类型进行处理,可以独立于任何类型运行
-
模板是泛型编程的基础,一个模板就是创建类或函数的蓝图或者公式,当我们在编译时提供了足够的参数后模板就会转换为特定的类或函数
-
模板分为函数模板和类模板两种,都可以通过参数形成特定的代码
-
函数模板的编写方法是在函数前用template<typename T>附注模板参数列表,然后这里声明的类型T可以被使用到函数是参数和定义中。
-
当我们调用函数模板时,编译器和以前一样可以自动按照我们的实参来推断模板参数的类型,如果想要指定类型则和使用泛型容器时一样在函数名后用尖括号标明所需要的具体类型T即可。在使用函数时,确定下来的类型会编译生成一个模板实例,实际运行的是这个模板实例
-
由关键字class或typename带头的参数称为类型参数,这两者没有区别但建议用typename
-
可以由具体关键字带头声明非类型参数,非类型参数表示的是一个值而不是类型,因此非类型参数在编译时会被用户提供或编译器推断的一个常量代替,从而允许我们初始化数组之类
-
非类型参数可以是整型或指向对象或函数的指针或左值引用,但是注意绑定到非类型整型必须是常量表达式,绑定到指针或引用的对象必须有静态的生存期(都是为了可以在编译期完成所要求的)
// 类型模板参数,模板函数
// 此处的T是作为一个待定类型使用的
template<typename T>
int typeTemp(T inp) {
return static_cast<int>inp;
// 非类型模板参数,模板函数
// 此处的N是作为一个待定常量表达式使用的
template<unsigned N>
int typeTemp(int inp[N]) {
return inp[0];
}