前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++】泛型编程 ② ( 函数模板与普通函数区别 )

【C++】泛型编程 ② ( 函数模板与普通函数区别 )

作者头像
韩曙亮
发布2023-11-16 08:14:36
2340
发布2023-11-16 08:14:36
举报
文章被收录于专栏:韩曙亮的移动开发专栏

一、函数模板与普通函数区别

1、函数模板与普通函数区别

函数模板与普通函数区别 : 主要区别在于它们能够处理的 数据类型数量 和 灵活性 ;

  • 自动类型转换 :
    • 函数模板 不允许 自动类型转化 , 会进行严格的类型匹配 ;
    • 普通函数 能够进行 自动类型转换 , 内含隐式的类型转化 ;
  • 参数 / 返回值 数据类型 :
    • 普通函数 只接受 特定类型 参数 , 如 : int / double / bool / string 等类型 ;
    • 函数模板 可以接受 任何类型 的参数 , 函数模板在 C++ 编译器 编译时 将类型参数实例化 , 生成对应的 普通函数 ;
  • 灵活性 :
    • 普通函数 对于 不同的 数据类型参数 需要单独定义 ; 例如 : 定义一个加法函数 , 接收参数类型分别是 int 和 float 类型 , 此时需要定义 2 个不同的函数 ;
    • 函数模板 只需要定义一个函数 , 就可以接收任何数据类型的参数 ;
  • 语法不同 :
    • 普通函数 直接定义 返回类型 , 函数名 , 参数列表 , 函数体 , 即可 完成函数定义 , 如 : int add(int a, int b){} ;
    • 函数模板 先使用 template <typename T> 声明泛型 , 后面跟着 返回类型 , 函数名 , 参数列表 , 函数体 , 等内容 , 在 函数的 参数列表 返回类型 中可使用 声明的 泛型类型 , 如 : T add(T a, T b){} ;
  • 函数模板实例化 : 使用函数模板时 , C++ 编译器会根据 实际传入的 参数类型 自动实例化相应的函数 ; 如 : 定义的 T add(T a, T b) 类型的 函数模板 , 如果传入 int 类型的参数 , 会自动创建 int add(int a, int b) 普通函数 ;
  • 函数模板弊端 - 复杂性 / 维护难度高 :
    • 复杂性 : 函数模板 需要为每一种可能的类型生成一个函数实例 , 所以 如果使用函数模板处理很多类型 , 需要创建很多普通函数实例 , 会导致编译时间增加 , 代码库增大 ;
    • 维护难度高 : 如果错误地使用 函数模板 可能会导致难以查找的错误 , 普通函数 更简单、更易于理解和维护。

2、代码示例 - 函数模板与普通函数区别

在下面的函数中 , 第一个调用场景 , 完全符合 普通函数 的 调用要求 , 优先调用 普通函数 ;

代码语言:javascript
复制
	int a = 10, b = 20;
	// 调用普通函数
	// 如果符合普通函数要求 优先调用普通函数
	int c = add(a, b);

第二个调用场景 , 因为使用了 函数模板 的显式调用 , 必须使用 函数模板 ;

代码语言:javascript
复制
	int i = 30, j = 40;
	// 调用函数模板
	// 函数模板 显式类型调用
	int k = add<int>(i, j);

第三个调用场景 , 参数类型不符合普通函数调用 , 符合 函数模板 的调用规则 , 这里使用 函数模板 ;

代码语言:javascript
复制
	double x = 50.0, y = 60.0;
	// 调用函数模板
	// 函数模板 自动类型推导
	double z = add(x, y);

代码示例 :

代码语言:javascript
复制
#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 . . .

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、函数模板与普通函数区别
    • 1、函数模板与普通函数区别
      • 2、代码示例 - 函数模板与普通函数区别
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档