【C++模板】:开启泛型编程之门(函数模版,类模板)

📝前言:
在上一篇文章C++内存管理中我们介绍了C++的内存管理,重点介绍了与C语言的区别,以及newdelete。这篇文章我们将介绍C++的利器——模板。
在C++编程世界里,模板是一项强大的特性,它为泛型编程奠定了坚实基础。借助模板,我们能够编写出与类型无关的通用代码,极大地提升代码复用性,减少重复劳动。接下来,让我们深入探索C++模板的奥秘。

🎬个人简介:努力学习ing
📋个人专栏:C++学习笔记
🎀CSDN主页 愚润求学
🌄其他专栏:C语言入门基础,python入门基础,python刷题专栏


文章目录

  • 一、函数模板
    • 1. 函数模板概念与格式
    • 2. 函数模板原理
    • 3. 函数模板实例化
    • 4. 模板参数匹配原则
  • 二、类模板
    • 1. 类模板定义格式
    • 2. 类模板实例化

一、函数模板

1. 函数模板概念与格式

函数模板就像一个函数家族的蓝图,该函数模板与类型无关,在使用时被参数化,编译器根据实参类型产生函数的特定类型版本。其格式如下:

template<typename T1, typename T2,......,typename Tn> 
返回值类型 函数名(参数列表){// 函数体
}

其中,typename是定义模板参数的关键字,也可用class替代(注意不能用struct)。例如,实现一个通用的加法函数模板:

template<typename T> // 只有一
T Add(const T& left, const T& right) {return left + right;
}

2. 函数模板原理

函数模板本身并非真正的函数,而是编译器用于生成具体类型函数的模具。在编译阶段,编译器会依据传入的实参类型,推演并生成相应类型的函数。比如:

int main() {int a = 10, b = 20;double c = 10.0, d = 20.0;Add(a, b); // 编译器将T推演为int,生成处理int类型的Add函数Add(c, d); // 编译器将T推演为double,生成处理double类型的Add函数return 0;
}

比如swap函数:
在这里插入图片描述

3. 函数模板实例化

当程序中调用函数模板并为类型参数指定具体类型时,编译器会根据该类型生成一个特定的函数实例。每个实例都是一个独立的函数,可以像普通函数一样被调用和执行。

  • 隐式实例化:让编译器根据实参自动推演模板参数的实际类型。不过,当实参类型无法唯一确定模板参数时会报错。例如:
int main() {int a = 10;double b = 20.0;// Add(a, b);  // 报错,无法确定T的类型(因为在这个模板的参数列表里面只有一个参数)// 解决方法一:用户强制类型转换Add(a, (int)b);// 解决方法二:使用显式实例化Add<int>(a, b)return 0;
}
  • 显式实例化:在函数名后的<>中明确指定模板参数的实际类型。如:
int main() {int a = 10;double b = 20.0;Add<int>(a, b); return 0;
}

多个参数的函数模版实例:

#include <iostream>// 函数模板,接受多个参数并打印它们
template<typename T1, typename T2, typename T3>
void printMultiple(const T1& a, const T2& b, const T3& c) {std::cout << "Values are: " << a << ", " << b << ", " << c << std::endl;
}int main() {int intValue = 1;double doubleValue = 2.5;char charValue = 'A';printMultiple(intValue, doubleValue, charValue);// 显式实例化:printMultiple<int, double, char>(intValue, doubleValue, charValue);return 0;
}

4. 模板参数匹配原则

  • 一个非模板函数可以和同名函数模板共存,且函数模板能实例化为该非模板函数。
  • 调用时,若其他条件相同,优先调用非模板函数;若模板能生成更匹配的函数,则选择模板。
  • 模板函数不允许自动类型转换,普通函数可以。例如:
// 专门处理int的加法函数
int Add(int left, int right) {return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right) {return left + right;
}
void Test() {Add(1, 2); // 调用非模板函数Add<int>(1, 2); // 调用模板函数实例化版本Add(1, 2.0); // 调用模板函数生成的更匹配版本
}

二、类模板

1. 类模板定义格式

template<class T1, class T2, ..., class Tn>
class 类模板名 {// 类内成员定义
};

以实现一个简单的栈类模板为例:

template<typename T>
class Stack {
public:Stack(size_t capacity = 4) {_array = new T[capacity];_capacity = capacity;_size = 0;}void Push(const T& data);
private:T* _array;size_t _capacity;size_t _size;
};
template<class T>
void Stack<T>::Push(const T& data) {// 扩容逻辑_array[_size] = data;++_size;
}

注意:类模板中可以定义成员函数模版,但是类模板里面的成员函数不一定是函数模版。

2. 类模板实例化

类模板实例化必须是显式实例化,即:需要在类模板名字后跟<>,并将实例化类型置于其中。类模板本身不是真正的类,实例化结果才是。例如:

int main() {Stack<int> st1; // 实例化出处理int类型的栈Stack<double> st2; // 实例化出处理double类型的栈return 0;
}

注意:模版不建议声明和定义分离到两个文件.h和.cpp,会出现链接错误


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

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

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

相关文章

Android : Camera之CHI API

来自&#xff1a; https://www.cnblogs.com/szsky/articles/10861918.html 一、CAM CHI API功能介绍&#xff1a; CHI API建立在Google HAL3的灵活性基础之上&#xff0c;目的是将Camera2/HAL3接口分离出来用于使用相机功能&#xff0c;它是一个灵活的图像处理驱动程序&#…

项目部署到生产上遇到的网络问题

今天项目上线不顺利,原因就是网络能 telnet 通过&#xff0c;但是就是访问不到接口。 项目使用的是 docker 部署的方式。一开始以为是网络权限没开通&#xff0c;一直找运维部门帮忙看&#xff0c;也都没发现问题&#xff0c;网络部门已经把权限都开了。 折腾了一番后&#x…

Odoo 18 中的列表视图装饰属性

引言 列表视图装饰在 Odoo 中提供了一种基于特定条件在列表/树形视图中直观突出显示记录或字段的方式。这些装饰能够提升用户体验&#xff0c;使用户更轻松地识别重要记录。在 Odoo 18 中&#xff0c;有多个属性可用于列表视图装饰&#xff0c;为数据管理提供了灵活性。 以下…

SpringMVC中有关请求参数的问题(映射路径,传递不同的参数)

目录 请求映射路径 get请求与psot请求发送普通参数 get请求发送参数 post请求发送参数 post请求乱码问题 5种参数类型传递 普通参数传递&#xff08;不同名&#xff09; 实体类对象传递 数组传递 集合参数 json数据传递参数 JSON数组 JSON对象 ​编辑 JSON引用集…

图片查看器:用PyQt5实现本地图片预览工具

通过python代码&#xff0c;基于PyQt5实现本地图片预览查看工具。 我们对窗口进行了圆角设计&#xff0c;图片的翻页按钮半透明处理&#xff0c;当鼠标移动至按钮上的动画效果&#xff0c;当选择某一张图片&#xff0c;进行左右翻页则轮播同目录所有支持的图片格式。 import …

算法优选系列(1.双指针_下)

目录 五. 有效三角形的个数&#xff08;medium&#xff09; 题目链接&#xff1a;有效三角形的个数 解法: 代码&#xff1a; 六&#xff1a;和为 s 的两个数字&#xff08;easy&#xff09; 题目链接&#xff1a;和为 s 的两个数字 解法&#xff1a; 代码; 七&#xf…

【数据结构】2算法及分析

0 章节 &#xff11;&#xff0e;&#xff14;到1&#xff0e;&#xff15;小节。 掌握算法概念、特性、描述、算法性能时间复杂度和空间复杂度&#xff1b; 理解递归含义&#xff1f; 掌握实现递归的条件和时机&#xff1b; 应用简单递归问题的算法设计&#xff1b; 重点 算法…

要在Unreal Engine 5(UE5)中实现角色打击怪物并让怪物做出受击反应,

UE5系列文章目录 文章目录 UE5系列文章目录前言一、实现思路二、最终效果 前言 ue5角色受击没有播放受击动画&#xff0c;主角达到怪物身上没有反应 一、实现思路 要在Unreal Engine 5&#xff08;UE5&#xff09;中实现角色打击怪物并让怪物做出受击反应&#xff0c;你需要…

Java糊涂包(Hutool)的安装教程并进行网络爬虫

Hutool的使用教程 1&#xff1a;在官网下载jar模块文件 Central Repository: cn/hutool/hutool-all/5.8.26https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.26/ 下载后缀只用jar的文件 2&#xff1a;复制并到idea当中&#xff0c;右键这个模块点击增加到库 3&…

C++从零实现Json-Rpc框架

文章目录 一、项目介绍1. 基本原理2. 涉及到的技术栈3. 最终实现的效果 二、 第三方库的介绍与使用1. JsonCpp库Json的数据格式JsonCpp介绍封装Json工具类 2. muduo库muduo库是什么Muduo库常见接口介绍 3. C11异步操作std::future 三、框架设计1. 服务端模块划分NetworkProtoco…

用伪元素和jquery实现tab标签切换(下标线样式)

HTML代码 <div class"title"><div class"tab-item active">按场景</div><div class"tab-item">按名称</div><div class"tab-item">按手机号</div> </div> CSS代码 .active{positio…

Python写一个查星座的小程序,适合初学者练手——字典和if语句练习

一、界面预览 二、完整代码 # 导入必要的库 import tkinter as tk from tkinter import ttk # 导入ttk模块用于更现代的控件 from PIL import Image, ImageTk # 用于处理图片 import os # 用于文件路径操作class ZodiacApp:def __init__(self, root):self.root rootself.r…

【A2DP】蓝牙A2DP协议剖析:从架构到规范

目录 一、A2DP 协议架构 1.1 A2DP 协议栈结构组成 1.2 协议栈各部分的关系与作用 二、设备配置与角色定义&#xff08;Configurations and roles &#xff09; 2.1 角色定义 2.2 配置示例与角色体现 三、用户需求与场景 3.1 用户需求与场景 3.2 协议限制 3.3 协议要求…

C语言for循环语句的用法(非常详细)

在 C语言中&#xff0c;除了 while 和 do while&#xff0c;使用 for 语句也可以实现循环结构。 C语言for循环的基本用法 for 循环语句的一般形式如下&#xff1a; for(表达式1;表达式2;表达式3) {语句块; } 有以下几点说明&#xff1a; for 是循环结构中的关键字之一。表…

Flutter 学习之旅 之 flutter 不使用插件,实现简单带加载动画的 LoadingToast 功能

Flutter 学习之旅 之 flutter 不使用插件&#xff0c;实现简单带加载动画的 LoadingToast 功能 目录 Flutter 学习之旅 之 flutter 不使用插件&#xff0c;实现简单带加载动画的 LoadingToast 功能 一、简单介绍 二、LoadingToast 三、简单案例实现 四、关键代码 一、简单…

289. 生命游戏

根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态&#xff1a; 1 即为 活细胞 &am…

滑动窗口及边缘化直观理解

文章目录 问题例子example求解思路边缘化边缘化原理边缘化的实际步骤marg先验约束公式先验约束公式1先验约束公式2 marg的问题及FEJ实例分析&#xff1a;VINS-Mono中的滑动窗口策略 边缘化的代码实现&#xff08;伪代码&#xff09; 参考 本文简要介绍VIO常用的滑动窗口及边缘化…

类和对象(下)

一.再谈构造函数 构造函数有构造函数体赋值实现和初始化列表两种方式 1.构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值. 虽然上述构造函数调用之后&#xff0c;对象中已经有了一个初始值&#xff0c;但是…

在资源有限中逆势突围:从抗战智谋到寒门高考的破局智慧

目录 引言 一、历史中的非对称作战&#xff1a;从李牧到八路军的智谋传承 李牧戍边&#xff1a;古代军事博弈中的资源重构 八路军的游击战&#xff1a;现代战争中的智慧延续 二、创业界的逆袭之道&#xff1a;小米与拼多多的资源重构 从MVP到杠杆解 社交裂变与资源错配 …

eLection: 1靶场渗透测试

eLection: 1 来自 <eLection: 1 ~ VulnHub> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182&#xff0c;靶场IP192.168.23.196 3&#xff0c;对靶机进行端口服…