初步认识C++模版

news2024/9/21 21:41:50

前言

在C语言中,我们知道函数的形参需要指定类型,但是在C++中,我们可以模版实现各种类型参数的通用函数。

1. 泛型编程

我们通过函数重载实现多种类型的同一作用的函数。如交换函数:

void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
void Swap(double& left, double& right)
{
double temp = left;
left = right;
right = temp;
}
void Swap(char& left, char& right)
{
char temp = left;
left = right;
right = temp;
}

但是这里有不好的地方:

1. 重载函数的代码复用率较低,当有新类型出现的时候,需要用户自己新增对应函数

2. 代码的可维护性较低,一个出错可能导致所有的重载进出错

因此,C++研究出了模版来实现函数的多类型形参使用。

2. 函数模版

2.1 什么是函数模版

函数模版代表了一整个函数体系,该函数模版与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

2.2 函数模版格式

template<typename T1,typename T2,......,typename Tn>

在交换函数中的使用:

template<typename T>
void swap(T& x,T& y)
{
  T temp = x;
  x = y;
  y = temp;
}

注意:typename可以用来定义模版参数关键字,也可以用class,但是不能用struct。

2.3 函数模版的原理

函数模版是一个蓝图,它本身并不是函数,是编译器使用方式产生的具体类型函数的模具。所以其实模版就是将我们该做的重复的事情交给了编译器。

在编译阶段,对于模版的使用,编译器根据传入的实参类型推演生成对应类型的函数以供调用。比如:当用double类型使用函数模版时,编译器通过推演,将T确定为double类型,然后产生一份专门处理double类型的代码。

2.4 函数模版实例化

当不同类型的参数使用函数模版时,称为函数模版的实例化。

模版实例化分为:隐式实例化和显式实例化。

1. 隐式实例化:让编译器根据实参推演模版参数的实际类型

template<class 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);
Add(d1, d2);
Add(a1,d1);
return 0;
}

这段代码是不能通过编译的,因为在第一个ADD的时候,模版将T推演为int类型,而第二个add则将T推演为double类型,然而模版参数列表只有一个T,所以会报错。

这时就需要处理,有两种方法:

1. 用户自己强制转换

Add(a1,(int )d1);

2. 使用显式实例化:在函数名后的<>中指定模版参数的实际类型

int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0;
}

如果类型不匹配,编译器会尝试进行隐式类型转换,如果不能转换成功则编译器会报错。

2.5 模版参数的匹配原则

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数

// 专门处理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版本
}

2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而 不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模版。

// 专门处理int的加法函数
int Add(int left, int right)
{
return left + right;
比特就业课
3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
3. 类模板
3.1 类模板的定义格式
}
// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
return left + right;
}
void Test()
{
Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的
Add函数
}

3. 类模版

3.1 定义格式

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

#include<iostream>
using namespace std;
// 类模版
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;
};
// 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误,具体原因后面会讲
template<class T>
void Stack<T>::Push(const T& data)
{
// 扩容
_array[_size] = data;
++_size;
}
int main()
{
Stack<int> st1; // int
Stack<double> st2; // double
return 0;
}

注意:每个函数模版定义后的作用域只在后面的一个短区域,因此需要定义多次函数模板。

3.2  类模版的实例化

类模版的实例化与函数模版不同,类模版的实例化需要在名字后面跟<>,将类型放在<>中间,类模板的名字不是真正的类,实例化的结果才是真正的类。

// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double

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

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

相关文章

力扣 167.两数之和||—输入为有序数组

文章目录 题目介绍解法 题目介绍 解法 利用相向双指针&#xff0c;初始时l在最用左边&#xff0c;r在最右边 1.numbers[l] numbers[r] < target 则 l 2.numbers[l] numbers[r] < target 则 r 3.numbers[l] numbers[r] target 说明找到了答案 class Solution {publi…

linux 操作系统下dhcrelay命令介绍和案例应用

linux 操作系统下dhcrelay命令介绍和案例应用 dhcrelay是一个用于DHCP&#xff08;动态主机配置协议&#xff09;中继的命令&#xff0c;主要功能是在没有本地DHCP服务器的子网中转发DHCP请求。这使得不同子网的DHCP客户端能够与位于其他子网中的DHCP服务器进行通信。 dhcrela…

基于YOLO算法的网球运动实时分析-击球速度测量-击球次数(附源码)

这个项目通过分析视频中的网球运动员来测量他们的速度、击球速度以及击球次数。该项目使用YOLO&#xff08;You Only Look Once&#xff09;算法来检测球员和网球&#xff0c;并利用卷积神经网络&#xff08;CNNs&#xff09;来提取球场的关键点。此实战项目非常适合提升您的机…

面向对象开发流程例题

答案;C 知识点 面向对象分析 认定对象 组织对象 对象间的相互作用 基于对象的操作 面向对象设计 识别类及对象 定义属性 定义服务 识别关系 识别包 面向对象程序设计 程序设计范型 选择一种OOPL 面向对象测试 算法层 类层 模板层 系统层

发布Java项目到Maven中央仓库

1.背景 本教程为2024年9月最新版 我有一个Java项目&#xff0c;想发布到Maven中央仓库&#xff0c;任何人都可以在pom文件中引用我的代码 引用格式如下&#xff08;以rocketmq为例&#xff09;&#xff1a; <dependency><groupId>org.apache.rocketmq</groupId…

鸿蒙开发之ArkUI 界面篇 十七 购物综合案例

layoutWeight:子元素与兄弟元素主轴方向按照权重进行分配,参数是联合类型&#xff0c;数字或者是字符串&#xff0c;在指定的空间占多少份额&#xff0c;数字越大&#xff0c;表示在空间中占用的份额越多&#xff0c;如果父容器的子组件没有别的指定&#xff0c;剩下的空间全部…

LeetCode[中等] 438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 思路&#xff1a;滑动窗口 s包含p的异位词 ——> 则…

如何导入一个Vue并成功运行

注意1&#xff1a;要确保自己已经成功创建了一个Vue项目&#xff0c;创建项目教程在如何创建Vue项目 注意2&#xff1a;以下操作均在VS Code&#xff0c;教程在VS Code安装教程 一、Vue项目导入VS Code 1.点击文件&#xff0c;然后点击将文件添加到工作区 2. 选择自己的vue项…

Java 每日一刊(第13期):this super static

“优秀的代码不仅仅是给机器看的&#xff0c;更是给人看的。” 前言 这里是分享 Java 相关内容的专刊&#xff0c;每日一更。 本期将为大家带来以下内容&#xff1a; this 关键字super 关键字static 关键字 this 关键字 this 关键字是 Java 中最常见的关键字之一&#xf…

数据中台系统产品原型RP原型Axure高保真交互原型 源文件分享

在数字化时代&#xff0c;数据已经成为企业最宝贵的资产之一。为了更好地管理和利用这些数据&#xff0c;这边为大家整理了一套数据中台Axure高保真原型。这套原型致力于为企业提供全方位的数据服务&#xff0c;助力企业实现数据驱动的创新发展。 下载及预览地址&#xff1a;h…

Spring自定义参数解析器

在这篇文章中&#xff0c;我们认识了参数解析器和消息转换器&#xff0c;今天我们来自定义一个参数解析器。 自定义参数解析器 实现HandlerMethodArgumentResolver的类&#xff0c;并注册到Spring容器。 Component&#xff0f;&#xff0f;注册到Spring public class UserAr…

目标拟合椭圆

对于目标区域&#xff0c;the ellipse fit is computing by matching second-order moments.

吉首大学--23级题目讲解

7-1 单链表基本操作 在 C/C 中&#xff0c;.&#xff08;点&#xff09;和 ->&#xff08;箭头&#xff09;运算符用于访问结构体或类的成员&#xff0c;但它们的使用场景不同。 1. . 运算符 . 运算符用于访问结构体或类的成员&#xff0c;通过对象或结构体变量直接访问。…

双虚拟机架构:在Linux上分别部署Nginx/PHP和MariaDB

在第一台虚拟机上安装 Nginx 和 PHP 更新软件包索引: sudo apt update安装 Nginx: sudo apt install nginx -y启动 Nginx 服务: sudo systemctl start nginx安装 PHP 和 Nginx 的 PHP 支持: sudo apt install php-fpm php-common -y配置 Nginx 以使用 PHP: 查看 PHP…

docker搭建个人网盘,支持多种格式,还能画图,一键部署

1&#xff09;效果 2&#xff09;步骤 2.1&#xff09;docker安装 docker脚本 bash <(curl -sSL https://cdn.jsdelivr.net/gh/SuperManito/LinuxMirrorsmain/DockerInstallation.sh)docker-compose脚本 curl -L "https://github.com/docker/compose/releases/late…

PostgreSQL(PG)(二十二)

&#x1f33b;&#x1f33b; 目录 &#x1f33b;&#x1f33b; 一、PostgreSQL 简介1.1、PG 的历史1.2、PG的社区1.2.1 纯社区1.2.2 完善的组织结构1.2.3 开源许可独特性 1.3 、PostgreSQL与MySQL的比较 二、PostgresQL的下载安装2.1、Windows上安装 PostgreSQL2.2、远程 连接 …

新能源汽车数据大全(产销数据\充电桩\专利等)

新能源汽车数据大全&#xff08;产销数据\充电桩\专利等&#xff09; 来源&#xff1a;全国各省市统计年鉴、统计公报、国家能源署、中国汽车行业协会&#xff0c;各类汽车统计年鉴、中国电动汽车充电基础设施促进联盟等 1、汽车分品牌产销(95家车企&#xff0c;768个车型&am…

项目第六弹:虚拟机管理模块、路由匹配模块

项目第六弹&#xff1a;虚拟机管理模块、路由匹配模块 一、虚拟机管理模块的设计1.什么是虚拟机&#xff1f;2.借助MySQL来理解一下3.如何整合&#xff1f;【埋下伏笔】 二、RabbitMQ为何要有虚拟机1.从业务角度来讲2.步步探索1.优点2.结合业务适用场景和需求3.发掘真正的原因4…

图神经网络模型的扩展(5)--1

1.深层图卷积网络 前面讲到&#xff0c;随着图卷积网络层数的叠加&#xff0c;其表达力反而会丢失&#xff0c;因为过深的图卷积网络会造成过平滑的现象。同时&#xff0c;在标准数据集上的实验结果似乎也可以佐证&#xff1a;在我们常用的Cora 等图数据集上&#xff0c;如图卷…

【AcWing】875. 快速幂

#include<iostream> using namespace std; typedef long long LL;LL qmi(int a,int b,int p){LL res1%p;//%p是为了p1的时候&#xff0c;余数是0while(b){if(b&1) resres*a%p;//位数是1的b>>1;aa*(LL)a%p;//a*a再modp是为了防止溢出}return res; }int main(){i…