函数模板与普通函数区别 : 主要区别在于它们能够处理的 数据类型数量 和 灵活性 ;
int add(int a, int b){}
;template <typename T>
声明泛型 , 后面跟着 返回类型 , 函数名 , 参数列表 , 函数体 , 等内容 , 在 函数的 参数列表 返回类型 中可使用 声明的 泛型类型 , 如 : T add(T a, T b){}
;T add(T a, T b)
类型的 函数模板 , 如果传入 int
类型的参数 , 会自动创建 int add(int a, int b)
普通函数 ;
在下面的函数中 , 第一个调用场景 , 完全符合 普通函数 的 调用要求 , 优先调用 普通函数 ;
int a = 10, b = 20;
// 调用普通函数
// 如果符合普通函数要求 优先调用普通函数
int c = add(a, b);
第二个调用场景 , 因为使用了 函数模板 的显式调用 , 必须使用 函数模板 ;
int i = 30, j = 40;
// 调用函数模板
// 函数模板 显式类型调用
int k = add<int>(i, j);
第三个调用场景 , 参数类型不符合普通函数调用 , 符合 函数模板 的调用规则 , 这里使用 函数模板 ;
double x = 50.0, y = 60.0;
// 调用函数模板
// 函数模板 自动类型推导
double z = add(x, y);
代码示例 :
#include "iostream"
using namespace std;
// 使用 template 关键字 声明函数模板
// 告诉 C++ 编译器 开始使用 泛型编程
// 定义的 T 是泛型类型
// 声明了多个泛型, 可以只使用其中的部分类型
// 使用函数模板时 , 显式类型调用 必须 显式指定所有 泛型类型 的实际类型
template <typename T>
T add(T a, T b) {
cout << "调用函数模板 T add(T a, T b)"<< endl;
return a + b;
}
// 函数模板的 重载函数
// 重载是发生在 同一个作用域中
// 重写是发生在 父类 与 子类 之间
// C++ 编译器优先 调用 符合要求的 普通函数
// 如果普通函数不符合要求 , 则考虑调用 函数模板
int add(int a, int b) {
cout << "调用普通函数 int add(int a, int b)" << endl;
return a + b;
}
// 普通函数 , 函数模板 调用 优先级
// 函数模板 会进行 严格类型匹配 , 不会进行 类型转换 ;
//
// 如果 符合 普通函数类型参数要求 , 优先调用普通函数 ;
// 如果 没有 符合要求的 普通函数 , 则查看 模板函数 能否匹配 ;
// 如果 模板函数 仍不能匹配 , 则查看 普通函数 类型转换能否匹配 ;
int main() {
int a = 10, b = 20;
// 调用普通函数
// 如果符合普通函数要求 优先调用普通函数
int c = add(a, b);
cout << "c = " << c << endl;
int i = 30, j = 40;
// 调用函数模板
// 函数模板 显式类型调用
int k = add<int>(i, j);
cout << "k = " << k << endl;
double x = 50.0, y = 60.0;
// 调用函数模板
// 函数模板 自动类型推导
double z = add(x, y);
cout << "z = " << z << endl;
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
}
执行结果 :
调用普通函数 int add(int a, int b) c = 30 调用函数模板 T add(T a, T b) k = 70 调用函数模板 T add(T a, T b) z = 110 Press any key to continue . . .