第16章_模板与泛型编程

  • 面向对象编程和泛型编程都能处理在编写程序时不知道类型的情况。不同之处在于:OOP 能处理类型在程序运行之前都未知的情况;而在泛型编程中,在编译时就能获知类型了。

定义模板

  • 除了定义类型参数,还可以在模板中定义非类型参数,一个非类型参数表示一个值而非一个类型。通过一个特定的类型名而非关键字 class 或 typename 来指定非类型参数。一个非类型参数可以是一个整型,或者是一个指向对象或函数类型的指针或(左值)引用。绑定到非类型整型参数的实参必须是一个常量表达式。绑定到指针或引用非类型参数的实参必须具有静态的生存期。
  • 当编译器遇到一个模板定义时,它并不生成代码。只有当我们实例化出模板的一个特定版本时,编译器才会生成代码。(这一特性影响了我们如何组织代码以及错误何时被检测到)
  • 为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义。因此,与非模板代码不同,模板的头文件通常既包括声明也包括定义。

函数模板

类模板

  • 与函数模板的不同之处是,编译器不能为类模板推断模板参数类型。为了使用类模板,我们必须在模板名后的尖括号中提供额外信息,用来代替模板参数的模板实参列表。
  • 定义在类模板内的成员函数被隐式声明为内联函数
  • 默认情况下,一个类模板的成员函数只有当程序用到它时才进行实例化
  • 在一个类模板的作用域内,可以直接使用模板名而不必制定模板实参

模板参数

成员模板

控制实例化

效率与灵活性

模板实参推断

类型转换与模板类型参数

函数模板显式实参

尾置返回类型与类型转换

函数指针和实参推断

模板你实参推断和引用

理解 std::move

转发

重载与模板

可变参数模板

编写可变参数函数模板

包拓展

转发参数包

模板特例化