C++ 模板初级

引入 

在讲函数模板之前就要先讲讲函数重载了

#include <iostream>
using namespace std;int add(int a, int b) {return a + b;
}double add(double a, double b) {return a + b;
}int main() {cout << add(2, 3) << endl;     cout << add(2.5, 3.7) << endl; return 0;
}

在上面代码我们可以知道除了内置类型不同其他的功能都是一样的,那既然重要功能都一样那我们能不能让它们合二为一,这样就可以处理多种数据类型的情况了,在C++中就可以使用函数模板来解决此类问题

一 函数模板:

概念:

函数模板允许我们编写与类型无关的函数。这样我们就可以在一次编写中处理不同的数据类型,而不必重复编写相同的代码。函数模板使用template关键字定义。

代码示例:

#include <iostream>
using namespace std;template <class T> //也可以 <typename T>
T add(T a , T b)
{return a + b;
}int main() {cout << add(2, 3) << endl;cout << add(2.5, 3.7) << endl; return 0;
}

这时我们是不是心里面有个疑问,为什么T知道我是什么数据类型,那下面请跟我详细分析

当编译器遇到模板函数的定义时编译器只记录模板的定义,并不会立即生成代码。编译器遇到函数调用add(2, 3):它推断参数23int类型,所以推断模板参数Tint。用int替换T,生成具体函数int add(int a, int b)。在这过程中虽然我们通过代码看到的依然时T但是内部已经全部换成了int类型了,所以说到底还是编译器承受的太多了。

还有一个疑惑就是我又调用了一个double那不是有两个类型了但是上面接收函数只有一个,编译器不会搞混吗?

编译器在编译过程中会生成两个具体的函数,一个用于int类型,一个用于double类型:

int add(int a, int b) {return a + b;
}double add(double a, double b) {return a + b;
}

因此,编译器会生成两个不同的函数实例,不会有混淆。

总结:

通过模板,我们可以编写更简洁、复用性更高的代码,而编译器会根据具体使用的类型生成对应的函数,不会混淆不同的类型。

模板实例化:

隐式实例化:

隐式实例化是指编译器根据实参推断模板参数的类型,然后实例化模板函数。

代码示例:

template <typename T>
T Add(const T& left, const T& right) {return left + right;
}int main() {int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, a2);  // T 被推断为 int,实例化为 int Add(const int&, const int&)Add(d1, d2);return 0;
}

显示实例化:

显式实例化是指在调用模板函数时明确指定模板参数的类型。

代码示例:

#include <iostream>
using namespace std;template <class T> //也可以 <typename T>
T add(T a , T b)
{return a + b;
}int main() {cout << add<int>(2, 3) << endl;cout << add<boudle>(2.5, 3.7) << endl; return 0;
}

总结:

  • 显式实例化:明确指定类型,适用于需要确定类型或编译器无法正确推断类型的情况。
  • 隐式实例化:代码更简洁,适用于编译器能够正确推断类型的情况。

非模板函数与函数模板:

当函数模板跟非函数模板在一起时,那咋们该怎么样调用呢?

  • 完全匹配的非模板函数:编译器首先会查找非模板函数,如果找到与参数完全匹配的非模板函数,就会优先选择它。
  • 匹配的模板函数:如果没有找到完全匹配的非模板函数,编译器会尝试使用模板函数进行匹配。模板函数的匹配过程包括模板参数推断和模板实例化。

代码示例:

#include <iostream>
using namespace std;// 专门处理 int 类型的加法函数
int Add(int left, int right) {return left + right;
}// 处理 double 类型的加法函数
double Add(double left, double right) {return left + right;
}// 通用加法函数模板
template <typename T1, typename T2>
auto Add(T1 left, T2 right) -> decltype(left + right) {return left + right;
}void Test() {cout << Add(1, 2) << endl;          // 调用非模板函数 Add(int, int)cout << Add(2.5, 3.5) << endl;      // 调用非模板函数 Add(double, double)cout << Add(1, 2.0) << endl;        // 调用模板函数 Add<int, double>(int, double)
}int main() {Test();return 0;
}

总结

  • 非模板函数优先:如果有一个非模板函数的参数类型完全匹配,编译器会优先选择它。
  • 模板函数其次:如果没有找到完全匹配的非模板函数,编译器会尝试使用模板函数进行匹配,并实例化一个具体的函数。
  • 模板的灵活性:模板函数可以接受不同类型的参数,并生成对应的具体函数,提供了更大的灵活性。

二 类模板:

概念:

类模板是C++中的一种机制,用于创建通用类,允许类的成员使用不特定的数据类型。类模板可以使代码更加通用和可重用,避免为每种数据类型编写重复的代码。

定义:

template <typename T>
class Box {
public:Box(T value) : _value(value) {}
private:T _value;
};
int main() {Box<int> intBox(123);           // 实例化 Box,T 为 intBox<double> doubleBox(45.67);
}

那在类模板中可不可以隐式实例化呢?

对于类模板,编译器不能自动推断模板参数的类型,必须显式指定。而对于函数模板,编译器确实可以根据传递的参数自动推断模板参数的类型。

对于类模板我们先讲这些到后面咋们慢慢补上

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

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

相关文章

pake 打包TodoList windows桌面应用exe

参考&#xff1a; rust安装 https://blog.csdn.net/weixin_42357472/article/details/125943880 pake网址 https://github.com/tw93/Pake 支持把网页打包成多终端应用 离线网站打包参考&#xff1a; https://github.com/tw93/Pake/wiki/Pake%E6%89%93%E5%8C%85%E9%9D%99%E6%8…

uniapp 小程序内嵌H5链接返回到小程序(亲测)

使用 weixin-js-sdk&#xff0c;特别注意的是&#xff0c;在vue项目中之前安装过 weixin-js-sdk 的&#xff0c;一定要要跟新&#xff0c;但是好像只可以更新到1.6.0版本&#xff0c;而微信要求最低版本是1.6.4&#xff0c;不过不影响使用。 安装weixin-js-sdk npm install w…

Unity Transform组件实现动画:基础与进阶技巧

在Unity中&#xff0c;Transform组件是控制游戏对象&#xff08;GameObject&#xff09;位置、旋转和缩放的核心组件。通过编程控制Transform组件&#xff0c;开发者可以创建各种动画效果。本文将介绍如何使用Transform组件实现动画&#xff0c;从基础的运动到更高级的动画技巧…

企业微信开发智能升级:AIGC技术赋能,打造高效沟通平台

文章目录 一、AIGC在企业微信开发中的核心价值1. 智能化客服体验2. 自动化工作流程3. 个性化内容推荐4. 深度数据分析与洞察 二、使用AIGC进行企业微信开发的实践路径1. 需求分析与场景定义2. 技术选型与平台搭建3. 模型训练与调优4. 接口对接与功能集成5. 测试与优化 《企业微…

Hugo 部署与自动更新(Git)

文章目录 Nginx部署Hugonginx.confhugo.conf Hugo自动更新Hugo自动更新流程添加访问令牌添加web hookrust实现自动更新接口 Nginx部署Hugo nginx.conf user nginx; worker_processes auto;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;even…

Lambda和Stream让代码简洁的七大原则

1. Lambda优于匿名内部类 函数接口&#xff1a;JDK 8中&#xff0c;只存在一个抽象方法的接口称为函数接口&#xff0c;使用FunctionalInterface注解标识。示例&#xff1a;FunctionalInterface public interface Comparator<T> {int compare(T o1, T o2); }Lambda表达式…

深入解读:几种常见视频大模型原理对比分析

在人工智能的快速发展中&#xff0c;视频分析技术逐渐成为研究的热点。伴随着深度学习的崛起&#xff0c;各种视频大模型应运而生&#xff0c;广泛应用于视频理解、动作识别、视频生成等领域。本文将对几种常见的视频大模型进行原理对比分析&#xff0c;帮助读者更好地理解它们…

JDK、JRE、JVM的区别

总结&#xff1a; JDK为开发人员提供了完整的开发和运行Java程序所需的工具和库&#xff0c;包括JRE、编译器&#xff08;javac&#xff09;、调试器&#xff08;jdb&#xff09;、Java类库&#xff08;如java标准库&#xff09;、基本开发工具&#xff1b; JRE为普通用户或需…

作业7.26~28

全双工&#xff1a; 通信双方 既可以发送&#xff0c;也可以接收数据 1. 利用多线程 或者 多进程&#xff0c; 实现TCP服务器 和 客户端的全双工通信 思路&#xff1a; 服务器和客户端&#xff0c; 在建立通信以后&#xff0c;可以创建线程&#xff0c;在线程编写另一个功能代…

实用网站推荐

​ 学习 前端 精简CSS格式 Font Awesome 图标库 BootCDN 加速服务 合集 AI工具集 动漫、音乐 娱乐 嗷呜动漫 奈飞同步 视频下载 B站视频解析下载 文件操作 ioDraw制作图 Convertio — 文件转换器 PDF处理 ​LOGO

python-小李帮老师改错(赛氪OJ)

[题目描述] 老师给小理发了一封电子邮件&#xff0c;任务如下。 写一个程序&#xff0c;给你 n 个数&#xff0c;输出 X。Xnum1p1​​num2p2​​⋯numnpn​​。 num1​&#xff0c;num2​&#xff0c;⋯⋯&#xff0c;numn​ 都是整数&#x…

图像处理 -- ISP的VA(Variation Accumulation)作用与实现原理

ISP的Variation Accumulation功能的作用与实现原理 ISP&#xff08;图像信号处理器&#xff09;的Variation Accumulation&#xff08;变异累积&#xff09;功能主要用于提高图像质量&#xff0c;尤其是在低光照条件下。其基本作用是通过对多帧图像的累积处理&#xff0c;降低…

sql注入和防止sql注入的方法

SQL注入&#xff08;SQL Injection&#xff09;是一种网络安全漏洞&#xff0c;允许攻击者在应用程序的SQL查询中插入恶意代码。这种攻击通常发生在应用程序没有正确验证或清理用户输入数据的情况下&#xff0c;导致攻击者能够操纵数据库查询&#xff0c;获取、修改或删除敏感信…

【脱敏】平台数据脱敏技术解决方案(word)

1 概述 1.1 数据脱敏定义 1.2 数据脱敏原则 1.2.1基本原则 1.2.2技术原则 1.2.3管理原则 1.3 数据脱敏常用方法 3.1.1泛化技术 3.1.2抑制技术 3.1.3扰乱技术 3.1.4有损技术 1.4 数据脱敏全生命周期 2 制定数据脱敏规程 3 发现敏感数据 4 定义脱敏规则 5 执…

02 Go语言开发REST API接口_20240728 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础 基础不好的同学每节课的代码最好配合视频进行阅读和学习&#xff0c;如果基础比较扎实&#xff0c;则阅读本教程巩固一下相关知识点即可&#xff0c;遇到不会…

探索Python监控之眼:watchdog库深度解析

文章目录 探索Python监控之眼&#xff1a;watchdog库深度解析1. 引言&#xff1a;为何选择watchdog&#xff1f;2. watchdog简介3. 安装watchdog库4. 基本函数与使用方法4.1 初始化监控器4.2 监控文件的创建4.3 监控文件的删除4.4 监控目录的创建4.5 监控目录的删除 5. 场景应用…

一文读懂JS事件循环、事件冒泡与事件委托

引言 JavaScript 是一种广泛使用的编程语言&#xff0c;特别是在前端开发领域。为了理解 JavaScript 中的异步行为和事件处理机制&#xff0c;我们需要深入了解事件循环、事件冒泡和事件委托等概念。本文将详细解释这些概念及其在实际编程中的应用。 1. JavaScript 事件循环 …

IoTDB 入门教程 实战篇②——MQTT集成

文章目录 一、前文二、配置参数三、开放端口四、MQTT客户端连接五、推送数据六、查询数据八、参考 一、前文 IoTDB入门教程——导读 IoTDB时序数据库内置MQTT服务器&#xff0c;允许远程设备将消息直接发送到IoTDB内置的MQTT服务器&#xff0c;并可以直接存入IoTDB时序数据库。…

gitee的远程连接与公钥SSH的连接

目录 1. 登录注册gitee1.1 登录注册1.2 创建仓库 2. 远程连接3. 公钥连接4. 参考链接 1. 登录注册gitee 1.1 登录注册 gitee官网 进入后进行登录注册 1.2 创建仓库 2. 远程连接 在你想要上传文件的文件夹中进行git初始化&#xff08;我在其他文章已经写过&#xff0c;链接…

新手小白,如何新建一个springboot的web项目?

第一步&#xff1a;打开软件&#xff0c;点击file&#xff0c;点击new 然后选择module&#xff0c;在右侧选择springboot 第二步&#xff1a;选择配置和JDK以及java版本 ①选择maven类型 ②选择JDK1.8版本 ③选择java8版本 ④选择jar包类型 http://t.csdnimg.cn/XeplRhttp:…