对应《c++ primer 第五版》的第16章前半部分,这里是一个简单的总结。
为了防止对每个不同的类型都定义一个函数,可以使用通用的模板,一个函数模板就是一个公式,可用来生成针对特定类型的函数版本。
模板定义以template开始,后面跟一个模板参数列表,用< >括起来。
模板定义中,模板参数列表不能为空。
模板参数列表就像函数的参数列表一样,在运行时要用实参来初始化形参。
当使用模板时,显式或隐式地指定模板实参,将其绑定到模板参数上。
比如定义了一个模板函数compare
template
int compare(const T &v1, const T &v2)
使用时,如果这样用
compare(1, 0)
就相当于instance化了一个特定版本的函数,T绑定了int。
声明为inline或者constexpr的,inline这个关键字要放在模板参数列表之后,返回类型之前,如下
template inline T min(const T&, const T&)
类型参数前必须使用关键字class 或 typename, 可以看到上面都用的是typename,
也可以用
template
因为typename是在模板已经广泛使用之后才引入cpp语言中的,所以一些程序员仍然只用class
每个类型参数前必须使用class 或者 typename, 下面这样做是不对的
template //这样不对,U前也必须用typename 或 class
【cpp|cpp 模板函数,类模板(1)】说下模板的编译:
编译器遇到一个模板定义时,并不生成代码,只有当实例化时才会生成代码。
大多数编译错误是在实例化期间报告的
第 1 阶段编译模板本身时,会检查语法错误,比如忘记分号。
第 2 阶段 编译器遇到模板使用时,对函数模板的调用,会检查实参数目是否正确。
第 3 阶段实例化时,只有这个阶段才能发现类型相关的错误,这类错误可能在link时才报告。
类模板:
类模板也是以关键字template开始,后面跟模板参数列表
template class Blob {
...
};
这里要说下阅读模板类代码时,要记住类模板的名字不是一个类型名,比如
template
bool SemanticsOcTreeNode>::isSemanticsSet() const
{
return this->semantics.isSemanticsSet();
}SEMANTICS semantics;
可以看到isSemanticsSet函数是semantics对象的函数,但是要知道SEMANTICS并不是一个类型名,它具体是什么类型,要看调用它的地方传的是什么实参类型。
和其他类相同,既可以在类模板内部,也可以在类模板外部定义其成员函数。
且定义在类模板内的成员函数被隐式声明为inline函数。
为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义,因此,函数模板和类模板成员函数的定义通常放在头文件中。
在类模板自己的作用域中,可以直接使用模板名而不提供实参,如下
template class B {
...
B& operator++();
//这里不需要指定B
};
但是,当定义在类模板外时,就要加上
friend class
如果模板类包含一个非模板friend class, 那么友元被授权可以访问所有模板实例,
如果友元自身是模板,类可以授权给所有友元模板实例,也可以只授权给特定实例。
具体下次再码。
推荐阅读
- C语言从0到1|【C语言】字符串函数
- Java知识点|Java的@Aspect的@Around切不到Controller导致Controller中@Autowired的Service为空
- 初学至学会C++|初阶C++——C++第二节——类和对象(大全篇)
- 初学至学会C++|初阶后的C++——第六节——IO流 与 继承
- 程序员|【python教程入门学习】普通人学python有意义吗
- C#|C# 关于sendtoback()和bringtofront() 的特点说明
- C#|C#中类的使用介绍
- CAD工程二次开发总结|CAD二次开发--像纬地与CASS程序一样双击桌面图标实现插件的自动挂载(不用netload也不用进入后输入挂载命令)
- js|逆向日记之发票查验平台网站js逆向分析及逆向算法