当前位置: 首页 > news >正文

详解 C++中的模板

目录

前言

一、函数模板

1.定义

2.函数模板的实现

3.模板函数的实例化

4.模板参数的省略

1.函数模板的实参推导

2.类模板的实参推导

3.默认模板参数

4.特殊情况:无法推导的模板

5.推导失败的情况

二、类模板

1.概念和定义

2.类模板定义

3.类模板的使用

4.类模板的定义格式


前言

        这篇文章主要介绍C++中的模板。

一、函数模板

1.定义

        模板是一系列相关函数的模型或样板,这些函数的源代码形式相同,只是所针对的数据类型不同。

        在开发过程中,我们经常遇到这种情况,有两个或者两个以上的函数,其功能是相同的,仅仅是数据类型的不同。例如:

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

        上面的三个函数都实现了对数据的加法运算,唯一不同的是参数类型不同。这样的函数可以采用函数模板实现简便化。

2.函数模板的实现

        函数模板的格式如下:

template <<模板形参声明>> <函数声明>

        模板形参是由一个或者多个<模板形参>组成的,如果是多个需要用逗号隔开。每个模板具有以下几种形式:

1.typename <参数名>

2.class <参数明>

3.<类型修饰><参数名>

        对于上述实例中的 add 函数,我们可以如下定义:

template <typename T>
T add(T a, T b) {return a + b;
}

3.模板函数的实例化

        在实际开发过程中,我们使用实参的实际类型代替虚拟类型即可。

#include <iostream>
#include <iomanip> // 需要包含这个头文件来设置精度
using namespace std;template <typename T>
T add(T a, T b) {return a + b;
}int main() {int a = 10, b = 20;cout << "a + b = " << add(a, b) << endl;// 使用浮点数并设置精度double c = 10.0, d = 20.0;cout << fixed << setprecision(2);  // 设置保留两位小数cout << "c + d = " << add(c, d) << endl;double e = 10.00, f = 20.00;cout << "e + f = " << add(e, f) << endl;return 0;
}

4.模板参数的省略

        在C++中,模板实参可以在某些情况下进行省略,称为 模板实参推导。这一特性允许编译器根据传递给函数或类的参数自动推导出模板的类型。以下是几种常见的模板实参省略场景:        

1.函数模板的实参推导

        对于函数模板,编译器可以根据调用时传递的函数参数来推导模板实参。例如:

template <typename T>
T add(T a, T b) {return a + b;
}int main() {int x = 5, y = 10;// 不需要显式指定类型,编译器会推导T为intcout << add(x, y) << endl;
}

        在上述例子中,add(x, y) 调用时,编译器会根据 x 和 y 的类型(int)自动推导 T 的类型为 int。

2.类模板的实参推导

        在C++17之前,类模板的实参必须显式指定,但从C++17开始,可以省略某些类模板的实参。编译器会从构造函数参数中推导出模板实参。例如:

template <typename T>
T add(T a, T b) {return a + b;
}int main() {int x = 5, y = 10;// 不需要显式指定类型,编译器会推导T为intcout << add(x, y) << endl;
}

        在这个例子中,Box box(123); 中并没有显式地指定 Box<int>,编译器根据传递的值 123 推导出 T 的类型为 int。

3.默认模板参数

        你可以为模板提供默认的模板参数,这样在不提供实参时会使用默认值。例如:

template <typename T = int>
T multiply(T a, T b) {return a * b;
}int main() {cout << multiply(3, 4) << endl; // T被推导为int,因为int是默认类型cout << multiply<double>(3.5, 2.5) << endl; // T显式为double
}

        在这个例子中,multiply(3, 4) 直接使用了默认的模板参数 T = int,而 multiply<double> 明确指定了模板参数。

4.特殊情况:无法推导的模板

        并非所有情况下模板都可以自动推导,特别是当模板类型不直接与参数关联时。例如,某些模板的类型依赖于非参数部分时,编译器无法自动推导,这时需要显式指定模板实参。

template <typename T, typename U>
void printPair(T a, U b) {cout << a << " and " << b << endl;
}int main() {printPair(1, "hello"); // 编译器能够推导T为int,U为const char*printPair<int>("test", 100); // 必须显式指定其中一个模板参数
}

5.推导失败的情况

        有时候模板的推导会失败,特别是类型不匹配或涉及复杂的类型转换时。此时需要显式指定模板实参来避免推导失败。

二、类模板

1.概念和定义

        类模板是通过引入模板参数来定义类的。在类模板的声明中,使用 template 关键字标识模板类型参数,然后在类的定义中可以使用这些模板参数,就像使用普通的数据类型一样。

2.类模板定义

        一个简单的类模板可以按如下方式定义:

template <typename T>
class Box {
private:T value;
public:Box(T val) : value(val) {}T getValue() {return value;}
};

        在上述代码中,T 是一个模板参数,可以被替换为任何具体的数据类型(例如 int、double 或 string)。当我们使用这个类时,必须在实例化类时提供一个具体的数据类型。

3.类模板的使用

        在这个例子中,Box<int> 和 Box<double> 分别创建了 int 和 double 类型的对象,并且它们可以分别存储 int 和 double 类型的数据。        ​​​​​​​        

int main() {Box<int> intBox(100);  // 使用int类型Box<double> doubleBox(100.5);  // 使用double类型std::cout << "intBox value: " << intBox.getValue() << std::endl;std::cout << "doubleBox value: " << doubleBox.getValue() << std::endl;return 0;
}

4.类模板的定义格式

        类模板的定义格式如下:

template <typename T> 
class ClassName {// 成员变量和方法使用模板参数T
};

        类模板的优势在于能够通过一种通用方式处理不同类型的数据,使代码更具通用性和灵活性,适用于需要同样逻辑但适用于不同数据类型的情况。

相关文章:

详解 C++中的模板

目录 前言 一、函数模板 1.定义 2.函数模板的实现 3.模板函数的实例化 4.模板参数的省略 1.函数模板的实参推导 2.类模板的实参推导 3.默认模板参数 4.特殊情况:无法推导的模板 5.推导失败的情况 二、类模板 1.概念和定义 2.类模板定义 3.类模板的使用 4.类模板…...

基于DAMODEL——Faster-RCNN 训练与测试指南

Faster-RCNN 训练与测试指南 前言 今天我们要来实现一个经典的目标检测模型&#xff1a;Faster-Rcnn。我们使用DAMODEL云平台来实现&#xff0c;这是个很强大的云端平台&#xff0c;功能众多&#xff0c;你可以投你所好去进行你想做的事情。 1. 环境与工具准备 1.1 远程连接…...

考研数据结构——C语言实现冒泡排序

冒泡排序是一种简单的排序算法&#xff0c;它重复地遍历要排序的列表&#xff0c;比较每对相邻元素&#xff0c;并在顺序错误的情况下交换它们。这个过程重复进行&#xff0c;直到没有需要交换的元素&#xff0c;这意味着列表已经排序完成。冒泡排序的名字来源于较小的元素会逐…...

labview更换操作系统后打开原VI闪退

labview更换操作系统后打开原VI闪退 问题描述&#xff1a; Windows11由家庭版更换为专业版后&#xff0c;重新安装labview2021&#xff0c;打开原来的项目&#xff0c;项目管理器可以正常打开&#xff0c;但是打开VI却闪退&#xff0c;并报错如下 出现这种原因主要是labview在…...

什么是CAPTCHA?有什么用途?

一、CAPTCHA 的工作原理 CAPTCHA的核心目的是通过呈现人类可以轻松理解但计算机程序难以解决的任务&#xff0c;来阻止恶意的自动化工具。传统的CAPTCHA通过展示扭曲或模糊的文字、图片或者点击操作等&#xff0c;要求用户完成验证任务。这些任务通常需要视觉、听觉或简单的逻辑…...

在虚幻引擎中创建毛发/头发

在虚幻引擎中创建毛发/头发 , 首先开启两个插件 Groom 和 Alembic Groom Importer 打开蒙皮缓存 导出人物模型 将人物导入Blender , 选择需要种植头发的点 指定并选择 点击毛发 这里变成爆炸头了 , 把数量和长度调一下 切换到梳子模式 调整发型 导出为abc , 文件路径不…...

PHP API 框架:构建高效API的利器【电商API接口】

在当今快速发展的互联网时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为连接不同应用程序和服务的关键。PHP&#xff0c;作为一种流行的服务器端脚本语言&#xff0c;提供了多种强大的框架来简化API的开发。本文将介绍PHP API框架的重要性&#xff0c;以及…...

transformer模型写诗词

加入会员社群&#xff0c;免费获取本项目数据集和代码&#xff1a;点击进入>> 1. 项目简介 该项目是基于A035-transformer模型的诗词生成系统&#xff0c;旨在通过深度学习技术实现古诗词的自动化创作。项目的背景源自当前自然语言处理领域的迅速发展&#xff0c;特别是…...

[大语言模型-工程实践] 手把手教你-基于Ollama搭建本地个人智能AI助理

[大语言模型-工程实践] 手把手教你-基于Ollama搭建本地个人智能AI助理 Note: 草稿优化中&#xff0c;持续更新&#xff0c;相关代码将统一提供出来~ 1. Ollama简介 Ollama 是一个用于在本地环境中运行和定制大型语言模型的工具。它提供了一个简单而高效的接口&#xff0c;用于…...

开放原子开源基金会OPENATOM

AtomGit_开放原子开源基金会代码托管平台-AtomGit 开放原子开源基金会是致力于推动全球开源事业发展的非营利机构&#xff0c;于 2020 年 6 月在北京成立&#xff0c;由阿里巴巴、百度、华为、浪潮、360、腾讯、招商银行等多家龙头科技企业联合发起。 精选项目&#xff1a; 比…...

Docker的监控:docker stats与docker events

Docker的监控:docker stats与docker events 1. 使用`docker stats`监控资源2. 使用`docker events`监控活动3、建议💖The Begin💖点点关注,收藏不迷路💖 Docker提供了docker stats和docker events两个简单而强大的工具来帮助我们监控容器。 1. 使用docker stats监控资…...

jvm专题 之 内存模型

文章目录 前言一个java对象的运行过程jvm内存分布程序的基本运行程序什么是对象&#xff1f;对象与类的关系&#xff1f;由类创建对象的顺序 前言 一个程序需要运行&#xff0c;需要在内存中开辟一块空间类是构建对象的模板&#xff0c;只有类加载到内存中才能创建对象 一个j…...

分布式计算框架

进入Scala模式 终端里输入Scala 创建一个新的Scala文件 vim 文件名.scala 复制粘贴代码 ctrlshift c/v 使用vim 先进入插入模式&#xff0c;可以通过按i键来实现&#xff0c;然后粘贴代码&#xff0c;完成后按Esc键退出插入模式&#xff0c;保存并退出可以通过输入:wq然后按…...

YOLO交通目标识别数据集(红绿灯-汽车-自行车-卡车等)

YOLO交通目标识别 数据集 模型 ui界面 ✓图片数量15000&#xff0c;xml和txt标签都有&#xff1b; ✓class&#xff1a;biker&#xff0c;car&#xff0c;pedestrian&#xff0c;trafficLight&#xff0c;trafficLight-Green&#xff0c;trafficLight-GreenLeft&#xff0c; t…...

Vue学习记录之六(组件实战及BEM框架了解)

一、BEM BEM是一种前端开发中常用的命名约定&#xff0c;主要用于CSS和HTML的结构化和模块化。BEM是Block、Element、Modifier的缩写。 Block&#xff08;块&#xff09;&#xff1a;独立的功能性页面组件&#xff0c;可以是一个简单的按钮&#xff0c;一个复杂的导航条&…...

为什么会出现电话机器人?语音电话机器人的出现起到了什么作用?

电话机器人的出现是科技发展与市场需求相结合的产物&#xff0c;它们的广泛应用反映了现代社会对效率、成本和服务质量的不断追求。以下是电话机器人出现的几个主要原因。 1. 市场需求的变化 随着经济的发展和消费模式的转变&#xff0c;客户对服务的期望不断提高。他们希望能…...

【CSS Tricks】深入聊聊前端编写css的方法论

目录 引言BEM 规范OOCSS 规范结构与样式分离容器与内容分离 SMACSS 规范ITCSS 规范设置层工具层通用层元素层对象层组件层微调层由此分层后的项目代码结构也会相应做修改&#xff0c;主要有两种形式&#xff1a;文件夹形式文件名形式引用方式按照层级顺序引用 ACSS 规范总结 引…...

多维时序 | GWO-VMD-SSA-LSTM灰狼优化变分模态分解联合麻雀优化长短期记忆网络多变量时间序列光伏功率预测(Matlab)

多维时序 | GWO-VMD-SSA-LSTM灰狼优化变分模态分解联合麻雀优化长短期记忆网络多变量时间序列光伏功率预测 目录 多维时序 | GWO-VMD-SSA-LSTM灰狼优化变分模态分解联合麻雀优化长短期记忆网络多变量时间序列光伏功率预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 …...

5.使用 VSCode 过程中的英语积累 - Go 菜单(每一次重点积累 5 个单词)

前言 学习可以不局限于传统的书籍和课堂&#xff0c;各种生活的元素也都可以做为我们的学习对象&#xff0c;本文将利用 VSCode 页面上的各种英文元素来做英语的积累&#xff0c;如此做有 3 大利 这些软件在我们工作中是时时刻刻接触的&#xff0c;借此做英语积累再合适不过&a…...

Java高级Day50-连接池

132.数据库连接池 传统获取Connection问题分析 传统的JDBC数据库连接使用DriverManager来获取&#xff0c;每次向数据库建立连接的时候都要将Connection加载到内存中&#xff0c;再验证IP地址&#xff0c;用户名和密码。需要数据库连接的时候&#xff0c;就向数据库请求一个&a…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...

Java多线程实现之Runnable接口深度解析

Java多线程实现之Runnable接口深度解析 一、Runnable接口概述1.1 接口定义1.2 与Thread类的关系1.3 使用Runnable接口的优势 二、Runnable接口的基本实现方式2.1 传统方式实现Runnable接口2.2 使用匿名内部类实现Runnable接口2.3 使用Lambda表达式实现Runnable接口 三、Runnabl…...

spring boot使用HttpServletResponse实现sse后端流式输出消息

1.以前只是看过SSE的相关文章&#xff0c;没有具体实践&#xff0c;这次接入AI大模型使用到了流式输出&#xff0c;涉及到给前端流式返回&#xff0c;所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...

华为云Flexus+DeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手

华为云FlexusDeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手 一、构建知识库问答助手引言二、构建知识库问答助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建知识库问答助手实战3.1 配置Dify环境3.2 创建知识库问答助手3.3 使用知…...