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

C++ 函数模板基础

文章目录

    • 一、什么是函数模板
    • 二、函数模板的优点
      • 1、代码重用
      • 2、类型安全
      • 3、可读性
      • 4、泛型编程
      • 5、性能优化
      • 6、库开发
    • 三、函数模板的使用场景
      • 1、通用操作
      • 2、数据结构与容器操作
      • 3、排序与查找算法
      • 4、数学与统计函数
      • 5、类型转换器
      • 6、自定义函数对象
    • 四、模板参数的声明(使用template关键字)
      • 1、类型参数声明
        • 1)示例1
        • 2)示例2
      • 2、非类型参数声明

一、什么是函数模板

  C++中的函数模板是用于创建泛型和可重用代码的一种编程范式。通过为编译器提供一组用于生成特定类型函数的模板,可以让同一段代码为多种类型的操作提供支持。在编译时,编译器根据函数模板和提供的类型将创建具体函数(实例化)。
  以下是一个C++函数模板的示例,表示计算两个数中的较大者的通用模板:

#include <iostream>
using namespace std;// 函数模板声明
template <typename T>
T maxNumber(T a, T b);int main() {int x = 3, y = 5;double u = 2.5, v = 1.8;// 使用模板函数,编译器自动推导类型int int_max = maxNumber(x, y);double double_max = maxNumber(u, v);cout << "Max of x and y = " << int_max << endl;cout << "Max of u and v = " << double_max << endl;return 0;
}// 函数模板定义
template <typename T>
T maxNumber(T a, T b) {return (a > b) ? a : b;
}

  在上述代码中,我们定义了一个函数模板 maxNumber,它有一个类型参数 T,用于泛化不同数据类型。此示例展示了如何使用同一个函数模板来处理多种类型的数据(在本例中,我们处理了intdouble数据类型)。编译器会根据提供的类型为该模板创建合适的函数实例。
  通过使用函数模板,我们可以编写通用、易于维护且可重用的代码。这可以简化大型项目中的复杂性,避免因重复编写类似代码而引入的错误。

二、函数模板的优点

  C++函数模板具有一些突出的优点,这使得它们在编写泛型和可重用代码时成为一个非常有用的工具:

1、代码重用

  通过使用函数模板,您可以编写一段能及时适应不同数据类型的代码,避免为处理不同数据类型编写多个类似的函数实现。这降低了代码重复度,同时减少了维护成本。

2、类型安全

  函数模板在编译时生成特定类型的函数实例,从而提供了额外的类型检查。这有助于捕获类型错误,确保程序的正确性,以及提高运行时性能。

3、可读性

  使用函数模板可以提高代码的可读性和透明度,因为您不再需要在代码中明确处理每个特定数据类型的情况,从而使代码更简洁。

4、泛型编程

  函数模板允许您实现泛型编程范式,这是一种设计和实现能够适应不同数据类型和情况的通用代码的方法。这可以提高代码的模块化和可扩展性。

5、性能优化

  由于模板实例化为特定类型的函数发生在编译时,因此可以提供优化的机会,与非模板函数相比,运行时性能相同或更好。

6、库开发

  在C++标准库和其他库中,函数模板被广泛用于实现通用算法、容器和其他实用程序,例如排序、查找、拷贝等操作。这提高了库的可重用性,并使库更易于集成。

  虽然函数模板具有诸多优点,但需要在编写和使用时注意避免编译器误解、代码膨胀、难以调试的问题。总的来说,合理使用C++函数模板可以带来代码编写和维护的极大便利。

三、函数模板的使用场景

  在C++中,函数模板用于编写通用的、能够适应多种数据类型的代码。以下是几个典型的函数模板使用场景:

1、通用操作

  编写适用于不同数据类型的通用操作函数,例如比较大小、求和、交换两个变量的值等。

template <typename T>
T getMax(T a, T b) {return (a > b) ? a : b;
}

2、数据结构与容器操作

  创建和操作通用数据结构,如链表、栈、队列、二叉树等。这种情况下,函数模板可用于实现类似查找、遍历、插入和删除等操作。

template <typename T>
bool findInVector(const std::vector<T>& vec, const T& value) {// ...
}

3、排序与查找算法

  实现通用的排序和查找算法,例如冒泡排序、快速排序、二分查找等。这些算法可以适应于基本数据类型和用户自定义对象,只要定义了适当的比较操作。

template <typename T>
void quickSort(std::vector<T>& data, int left, int right) {// ...
}

4、数学与统计函数

  实现泛型数学和统计函数,如最大公约数、最小公倍数、平均值计算等。

template <typename T>
T gcd(T a, T b) {// ...
}

5、类型转换器

  编写通用的类型转换器函数,例如在编码/解码器、序列化/反序列化等场景中。

template <typename To, typename From>
To convertType(const From& source) {// ...
}

6、自定义函数对象

  创建泛型的仿函数(函数对象),这些可用于执行操作(例如比较、转换等)并在传递给其他泛型函数时保持状态。

template <typename T>
class CustomComparator {// ...bool operator()(T a, T b) const {// ...}
};

  在这些使用场景中,函数模板提供了灵活性和可重用性,使得你能够为不同数据类型编写一段代码。唯一的挑战是有效地管理类型参数,使其适应于所需的操作和逻辑。使用C++中的函数模板可以帮助你编写更加高效、可维护的代码。

四、模板参数的声明(使用template关键字)

  在C++中,模板参数(可以是类型参数或非类型参数)在函数模板定义前使用template关键字进行声明。以下是模板参数声明的基本语法:

template <typename/type/class T, typename/type/class U, ... , typename/type/class N, NonTypeParameter1, NonTypeParameter2, ..., NonTypeParameterN>

  这里,TUN表示类型参数,你可以使用typenameclass关键字定义它们。NonTypeParameter1NonTypeParameter2NonTypeParameterN表示非类型参数(例如整数、字符或者指针等)。

1、类型参数声明

1)示例1

  以下是一个使用单个类型参数的简单函数模板,实现任意类型变量的交换:

template <typename T> // 声明一个类型参数T
void swap(T& a, T& b) {T temp = a;a = b;b = temp;
}

2)示例2

  以下是一个使用两个类型参数的函数模板,用于计算一对具有不同类型的值之和:

template <typename T, typename U> // 声明两个类型参数T和U
auto sum(T a, U b) -> decltype(a + b) {return a + b;
}

2、非类型参数声明

  非类型参数表示一个编译时常量,如整数、枚举值、指针等。
以下是一个使用非类型整数参数N的数组求和函数模板:

template <typename T, int N> // 声明一个类型参数T和一个非类型整数参数N
T arraySum(const T (&arr)[N]) {T sum = T();for (int i = 0; i < N; ++i) {sum += arr[i];}return sum;
}

  现在你已经了解了如何在C++中声明模板参数。使用模板参数可以帮助你编写更通用的代码,减少代码重复,并提高代码的可维护性。在C++编程中,模板参数是一个非常重要且强大的工具。


  太多内容记不住?前往👉🏻 英雄算法联盟 和博主一起刷题,巩固知识点 和 加深印象。

相关文章:

C++ 函数模板基础

文章目录 一、什么是函数模板二、函数模板的优点1、代码重用2、类型安全3、可读性4、泛型编程5、性能优化6、库开发 三、函数模板的使用场景1、通用操作2、数据结构与容器操作3、排序与查找算法4、数学与统计函数5、类型转换器6、自定义函数对象 四、模板参数的声明&#xff08…...

CUDA torch reinstall 与杂谈

一 实用技巧 1 从cuda11升级到12 apt-get --purge remove "cuda*" wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda_12.1.1_530.30.02_linux.run sh cuda_12.1.1_530.30.02_linux.run vim ~/.bashrc export PATH/usr/local…...

[230530] 托福TPO口语真题| TPO66~TPO72|XPO|Task1|20:30~21:00

目录 真题 预测题​​​​​​​ 真题 66. Do you agree or disagree with the following statement? Some people believe that a person needs a college education in order to have a successful career. Others believe that a college education is not necessary for…...

【FMC201】基于FMC标准的1路CameraLink Full 输入 子卡模块

产品概述 FMC201是一款CameraLink信号输入&#xff08;采集&#xff09;FMC子卡模块&#xff0c;该模块支持2路CameraLink Base模式或者1路CameraLink Full模式的图像信号输入。板卡具有2个CameraLink端口&#xff08;SDR26&#xff09;&#xff0c;可以作为采集卡使用。 技术指…...

C语言_VS系列编译器写C语言或C++代码产生的一些错误与警告的解决方法(VS2010/VS2019)

本次来分享在用VS系列编译(VS2010/VS2019)写C语言或C代码时会遇到的一些警告和错误&#xff0c;提供博主的一些解决方法&#xff0c;若有更好的解决方法&#xff0c;大家也可以在评论区发表自己的意见噢&#xff0c;话不多说&#xff0c;开始上菜&#xff1a; 此博主在CSDN发布…...

从零实现一个数据库(DataBase) Go语言实现版 0.介绍

英文源地址 数据库实现步骤细分 1.持久化(Persistence) 我们为什么需要数据库?为什么不是直接把数据dump进文件中. 第一个话题就是持久化. 我们将讨论如果写入文件的过程中程序崩溃了, 或者电源断电了, 文件的状态会是什么样的呢? 文件是否只是丢失了最后一次写操作?或者…...

操作系统-X18 linux日志审计

Linux日志审计 在unix/类unix&#xff08;Linux&#xff09;系统中&#xff0c;日志是内核&#xff08;内存&#xff09;的一部分。 用于记录系统、程序运行中发生的各种事件 通过阅读日志&#xff0c;有助于诊断和解决系统故障 日志文件的分类 ①内核及系统日志 由系统sysl…...

【Vue工程】011-Axios

【Vue工程】011-Axios 文章目录 【Vue工程】011-Axios一、概述1、简介2、官网3、訾博其他相关博客【axios】001-axios概述、特点、文档说明【axios】002-axios发起请求axios封装 二、基本使用1、安装2、创建一个 token 状态3、axios 封装4、使用示例设置 baseURL请求调用拦截器…...

Cy7 NHS ester水溶性七甲川花菁染料标记活性脂477908-53-5

Sulfo-CY7 NHS ester是一种荧光标记试剂&#xff0c;可用于生物分子的荧光标记。它是一种水溶性的N-羟基琥珀酰亚胺酯化合物&#xff0c;具有强烈的荧光信号和高度稳定性。Sulfo-CY7 NHS ester的化学结构为C43H48N3NaO16S2&#xff0c;分子量约为968.98 g/mol。Sulfo-CY7 NHS e…...

利用CX-ONE搭建omron PLC仿真环境

目录 1 安装参考 2 CX-Simulator 2.1 打开软件 2.2 选择PLC配置文件存放位置 2.3 选择PLC类型 2.4 PLC Unit全部选择 2.5 设置FINS通讯 2.6 设置串口通讯 2.7 建立连接 3 CX-Programmer 3.1 新建工程 3.2 设置PLC型号 3.3 设置网络类型 3.4 设置串口通讯 3.5 设…...

webpack Plugin Loader

本文作者为 360 奇舞团前端开发工程师 webpack是Javascript工具链的关键部分。webpack是个用于现代JavaScript应用程序的静态模块打包工具。它不仅可以支持ESM和CommonJS模块化编程&#xff0c;而且还可以支持或扩展支持许多不同的静态资源&#xff0c;例如&#xff1a;Files,I…...

关闭eslint - vue篇

文章目录 一、问题描述二、问题解决1、首先是比较旧的vue项目2、创建项目的时候&#xff0c;不要选eslint3、如果你使用的编辑软件是webstorm4、创建的项目没有webpack.base.conf.js文件&#xff0c;但是有 .eslintrc.js5、比较新的vue项目&#xff0c;目录没有&#xff08;直接…...

XXL-SSO简要说明

一、介绍 XXL-SSO 是一个分布式单点登录框架。只需要登录一次就可以访问所有相互信任的应用系统。 拥有”轻量级、分布式、跨域、CookieToken均支持、WebAPP均支持”等特性。现已开放源代码&#xff0c;开箱即用。 官方文档 二、集成 2.1、源码下载 下载地址 2.2、代码结构…...

HC-05蓝牙模块的使用

我最近刚刚开始学习嵌入式&#xff0c;在第一次使用蓝牙模块HC-05的时候遇到了很多问题&#xff0c; 甚至连接线都不会&#xff0c;因此下面我会十分详细地介绍我一步一步探索的步骤&#xff0c;直到完成使用手机APP和51单片机收发数据。 调试步骤 首先&#xff0c;我们需要明…...

初始python

初始python 缘由 ​ 对于python&#xff0c;相比大家并不陌生&#xff0c;Python是一种高级的、解释性编程语言&#xff0c;它具有简洁的语法和强大的内置函数&#xff0c;适用于广泛的应用领域&#xff0c;例如运维,Web开发&#xff0c;数据科学&#xff0c;人工智能等。Pyt…...

C++入门预备语法

C入门预备语法 C关键字命名空间C输入&输出初步缺省参数函数重载引用内联函数auto和范围for&#xff08;C11&#xff09;指针空值nullptr C关键字 命名空间 命名空间是一种将变量名、函数名、类名和库名称等封装到一个命名空间域中&#xff0c;与其他域的同名量相隔离&…...

python发送email

通过第三方SMTP发送纯文本邮件 #!/usr/bin/python -- coding: UTF-8 -- import smtplib from email.mime.text import MIMEText from email.header import Header 第三方 SMTP 服务 mail_host“smtp.XXX.com” #设置服务器 mail_user“XXXX” #用户名 mail_pass“XXXXXX” …...

软件测试面试题自动化面经分享——这才是高薪的秘诀!

Hello&#xff0c;你们的好朋友来了&#xff01;今天猜猜我给大家带来点啥干货呢&#xff1f;最近很多小伙伴出去面试的时候经常会被问到跟自动化测试相关的面试题。所以&#xff0c;今天特意给大家整理了一些经常被公司问到的自动化测试相关的面试题。停&#xff0c;咱先收藏起…...

Ceph入门到精通-Centos8安装prometheus

普罗米修斯是一个开源的监控、查询和警报工具。最初由Soundcloud于2012年构建,功能丰富的工具已被多家公司采用,用于监控其IT基础架构并确保所有系统平稳运行。Prometheus 允许您通过 HTTP 协议查询和提取时间序列指标,例如 CPU 和内存利用率,并在实时图表上可视化它们。您…...

把树莓派改造成无线网卡(3)-----共享无线网络,无线网络转换成有线网络,让有线网络设备连上无线网络

本文目录 1、准备工作2、安装DNS和配置管理软件3、设置网络路由功能3.1、树莓派的有线网络接口IP配置3.2、启用路由和IP伪装3.3、为有线网络配置DHCP和DNS服务 4、运行5、进阶--将二个以太网口加入到同一个网桥 现在的无线路由器非常便宜&#xff0c;所以实际上除了有特殊的要求…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...