C++ Primer 之函数模板

函数模板是通用的函数描述,通过将类型作为参数传递给模板,使编译器生成可用具体的类型的函数。类似于:

template<class Any>
void swap(Any &a, Any &b);

对于不同类型使用同一种算法,可使用模板,有时需要像重载常规函数那样去重载函数模板。

void swap(Any &a, Any &b);
void swap(int &a, int &b);

假设:

struct job
{ 
char name[10];
int floor;
};

假设我们希望交换两个job结构的内容,直接互换job即可,但有时候我们只想交换name,不交换floor,但函数的参数列表是一样的,无法使用模板重载来提提供其他的代码,此时需要涉及到具体化函数的定义,即指定某个函数定义,不再匹配模板。

实例化和具体化

在代码中包模板本身不会生成函数定义,编译器会根据具体参数类型生成模板的具体实例,这种叫隐式实例化。如今C++允许显示实例化,意味着直接命令编辑器创建特定的实例,语法是在函数声明前加template:

template void swap<int>(int &, int &); 

此外还可以显示具体化(一下二者等价)

template <> void swap<int>(int &, int &); 
template <> void swap(int &a, int &b);

隐式实例化,显示实例化和具体实例化统称具体化,都表示使用具体的函数定义,而不是通用描述。再声明中使用前缀template和template<>来区分显示实例化和具体化。显示具体化必须有自己的定义,实例化不需要有自己的定义。
警告:试图在同一个编程单元中使用同一类型的显示实例和显示具体化将出错。
#具体化函数将覆盖常规函数,而非模板函数将覆盖具体化和常规模板!

编译器的选择

编译器通常会对参数进行所需要的转换,选择是从最佳到最差的顺序如下:

  1. 完全匹配,但常规函数优于模板。(两个完全匹配的模板,较具体的优先,显示具体化优于隐式)
  2. 提升转换(例如:char和shorts转int,floor自动转double)
  3. 标准转换(例如: int转char)
  4. 用户自定义转换
template <class Type> void f(Type T);   //#1
template <class Type> void f(Type *T);  //#2
struct blot {int a, char b[10];};
blot link = {25, "sport");
f(&link);

f(&link)与#1,#2都匹配,具体参照完全匹配,但是#2更具体,#1还需要将转换为指针,因为参数不需要再转换已经具体化为指针了。

完全匹配允许的无关紧要转换

输入图片说明
输入图片说明
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,552评论 1 51
  • C++ 模板简介 一、模板 使用模板的目的就是能够让程序员编写与类型无关的代码。 模板是一种对类型进行参数化的工具...
    MinoyJet阅读 2,437评论 0 12
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,206评论 19 139