14.1 概述
- 所谓函数模板(function template),实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。
- 凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
14.2 函数模板语法
14.2.1 定义
14.2.2 调用
(1)隐式调用(自动类型推导)
(2)显式调用(指定类型)
示例代码:
#include <iostream>
using namespace std;
/*
int add(int x, int y)
{
return x + y;
}
double add(double x, double y)
{
return x + y;
}*/
template <typename T> //声明虚拟类型T(作用域只局限于下面紧跟的一个函数)
T add(T x, T y)
{
return x + y;
}
template <typename T>
void show(T x)
{
cout << x << endl;
}
template <typename T1, typename T2>
void print(T1 x, T2 y)
{
cout << x << y << endl;
}
int main()
{
cout << add(1, 2) << endl; //隐式调用(自动数据类型推导)
cout << add(1.11, 2.22) << endl;
cout << add<int>(1, 'a') << endl; //显示调用(指定转换为int类型)
cout << add<char>(1, 'a') << endl; //显示调用(指定转换为char类型)
print(1, 'a');
print<double, char>(1.11, 'a');
show(1);
return 0;
}
运行结果:
14.3 函数模板遇上函数重载
14.3.1 函数模板和普通函数区别
- 函数模板不允许自动类型转化
- 普通函数能够进行自动类型转换
14.3.2 函数模板和普通函数在一起调用规则
- 1 函数模板可以像普通函数一样被重载
- 2 C++编译器优先考虑普通函数
- 3 如果函数模板可以产生一个更好的匹配,那么选择模板
- 4 可以通过空模板实参列表的语法限定编译器只通过模板匹配
注意:普通函数和模板函数同时存在,优先调用普通函数
示例代码:
#include <iostream>
using namespace std;
int add(int x, int y)
{
cout << "普通函数" << endl;
return x + y;
}
template <typename T>
T add(T x, T y)
{
cout << "模板函数" << endl;
return x + y;
}
template <typename T>
void show(T x, T y)
{
cout << x << y << endl;
}
int main()
{
cout << add(1, 'a') << endl; //普通函数可以进行默认类型转换
show<int>(1, 'a'); //模板函数没有默认的类型转换
add(1, 2); //普通函数和模板函数同时存在,优先调用普通函数
return 0;
}
运行结果:
14.4 函数模板机制
- 编译器并不是把函数模板处理成能够处理任意类的函数
- 编译器从函数模板通过具体类型产生不同的函数
- 编译器会对函数模板进行两次编译
- 在声明的地方对模板代码本身进行编译;在调用的地方对参数替换后的代码进行编译。