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

文章目录

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






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




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、代码示例 - 函数模板与普通函数区别


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

	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 . . .


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/179441.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion (version x.x) 文生图模型实践指南

前言&#xff1a;本篇博客记录使用Stable Diffusion模型进行推断时借鉴的相关资料和操作流程。 相关博客&#xff1a; 超详细&#xff01;DALL E 文生图模型实践指南 DALLE 2 文生图模型实践指南 目录 1. 环境搭建和预训练模型准备环境搭建预训练模型下载 2. 代码 1. 环境搭建…

8.查询数据

一、单表查询 MySQL从数据表中查询数据的基本语为SELECT语。SELECT语的基本格式是: SELECT {* | <字段列名>} [ FROM <表 1>, <表 2>… [WHERE <表达式> [GROUP BY <group by definition> [HAVING <expression> [{<operator>…

POE也收费了

一直通过POE在用chatgpt&#xff0c;今天下午发现要收费了…

想买GPT4会员却只能排队?来看看背后的故事!

文章目录 &#x1f9d0; 为什么要进候选名单&#xff1f;&#x1f50d; 究竟发生了什么&#xff1f;&#x1f62e; IOS端还能买会员&#xff01;&#x1f914; 网页端为啥不能订会员&#xff1f;第一点&#xff1a;防止黑卡消费第二点&#xff1a;当技术巨头遇上资源瓶颈&#…

使用MathType将文献中的数学公式进行转换

mathtype将文献中的数学公式进行转换 文章目录 mathtype将文献中的数学公式进行转换一、截图识别二、MathType下载与设置2.1、MathType介绍2.2、[下载位置](http://www.51xiazai.cn/soft/5975.htm)2.3、设置 三、使用MathType&#xff1a; 一、截图识别 这两个在线网站都可以将…

Linux是什么,Linux系统介绍

很多小伙伴都不是那么了解和知道Linux&#xff0c;到底Linux是什么&#xff1f; 像大家用到的安卓手机&#xff0c;生活中用到的各种智能设备&#xff0c;比如路由器&#xff0c;光猫&#xff0c;智能家具等&#xff0c;很多都是在Linux操作系统上。 Linux是什么&#xff1f;Li…

指针传2

几天没有写博客了&#xff0c;怎么说呢&#xff1f;这让我总感觉缺点什么&#xff0c;心里空落落的&#xff0c;你懂吧&#xff01; 好了&#xff0c;接下来开始我们今天的正题&#xff01; 1. ⼆级指针 我们先来看看代码&#xff1a; 首先创建了一个整型变量a&#xff0c;将…

【开源】基于Vue和SpringBoot的快乐贩卖馆管理系统

项目编号&#xff1a; S 064 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S064&#xff0c;文末获取源码。} 项目编号&#xff1a;S064&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 搞笑视频模块2.3 视…

模拟业务流程+构造各种测试数据,一文带你测试效率提升80%

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Java设计模式-结构型模式-适配器模式

适配器模式 适配器模式应用场景案例类适配器模式对象适配器模式接口适配器模式适配器模式在源码中的使用 适配器模式 如图&#xff1a;国外插座标准和国内不同&#xff0c;要使用国内的充电器&#xff0c;就需要转接插头&#xff0c;转接插头就是起到适配器的作用 适配器模式&…

Django之模版层

文章目录 模版语法传值模版语法传值特性模版语法标签语法格式if模板标签for模板标签with起别名 模版语法过滤器常用过滤器 自定义过滤器、标签、inclusion_tag自定义过滤器自定义标签自定义inclusion_tag 模版导入模版继承 模版语法传值 模板层三种语法{{}}:主要与数据值相关{%…

C语言不可不敲系列:跳水比赛排名问题

目录 1题干&#xff1a; 2解题思路&#xff1a; 3代码: 4运行结果: 5总结: 1题干&#xff1a; 5位运动员参加了10米台跳水比赛&#xff0c;有人让他们预测比赛结果 A选手说&#xff1a;B第二&#xff0c;我第三&#xff1b; B选手说&#xff1a;我第二&#xff0c;E第四&am…