C++ 编程基础(8)模版 | 8.2、函数模版
文章目录
- 一、函数模版
- 1、声明与定义
- 2、模版参数
- 3、模板的实例化
- 3.1、隐式实例化
- 3.2、显示实例化
- 4、模版的特化
- 5、注意事项
- 6、总结
前言:
C++ 函数模板是一种强大的特性,它允许程序员编写与类型无关的代码。通过使用模板,函数或类可以处理不同的数据类型,而无需重复编写代码。这种机制提高了代码的可重用性和灵活性。本文将详细介绍C++中的函数模板,包括其定义、使用、实例化以及模板的特化。
一、函数模版
1、声明与定义
函数模板的定义以
template关键字开头,后面跟着一个模板参数列表(用尖括号< >包围)。模板参数列表中的参数可以是类型参数,也可以是非类型参数(如整数常量)。以下是一个简单的函数模板示例,用于计算两个值的最大值:
#include <iostream>// 定义一个函数模板
template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}int main() {int intVal1 = 5, intVal2 = 10;double doubleVal1 = 5.5, doubleVal2 = 4.4;std::cout << "Max of int values: " << max(intVal1, intVal2) << std::endl;std::cout << "Max of double values: " << max(doubleVal1, doubleVal2) << std::endl;return 0;
}
2、模版参数
除了类型参数(
typename或class关键字定义),C++ 函数模板还支持非类型参数。非类型参数通常在模板参数列表中定义,可以包括以下几种形式:
- 整型常量:如
int N - 枚举常量:如
enum E { A, B } e - 指针或引用:如
int* ptr或const char& c - 模板类型:如
typename T::value_type
以下是一个简单的示例,展示如何使用非类型参数来创建一个通用的幂运算函数:
#include <iostream>// 带有非类型参数的模板函数
template <typename T, int N>
T power(T a) {T result = 1;for (int i = 0; i < N; ++i) {result *= a;}return result;
}int main() {std::cout << "2^3 = " << power<int, 3>(2) << std::endl; // 输出: 2^3 = 8std::cout << "4^2 = " << power<double, 2>(4) << std::endl; // 输出: 4^2 = 16.0return 0;
}
3、模板的实例化
在代码中包含模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。当编译器遇到一个函数模板调用时,它会尝试根据提供的参数类型实例化模板。如果成功,编译器会生成相应的函数代码。这个过程称为模板实例化。常见的三种实例化方法分别是:隐式实例化,显示实例化和模版的特化。
3.1、隐式实例化
隐式实例化是指在调用函数模板时,如果没有找到匹配的函数或函数模板,编译器会自动根据传入的参数类型来实例化模板。这种方式不需要程序员显式地指定模板参数,编译器会根据参数自动推导出模板参数的类型。例如:
#include <iostream>// 通用模板函数
template <typename T>
void print(T value) {std::cout << "Value: " << value << std::endl;
}int main() {print(42); // 隐式实例化为 print<int>(42)print(3.14); // 隐式实例化为 print<double>(3.14)print("Hello"); // 隐式实例化为 print<const char*>("Hello")return 0;
}
3.2、显示实例化
使用
template关键字通过显示声明的方式告诉编译器需要对某个特定类型进行实例化。例如:
#include <iostream>// 通用模板函数
template <typename T>
void print(T value) {std::cout << "Value: " << value << std::endl;
}// 显式实例化声明
template void print<int>(int);
template void print<double>(double);
template void print<const char*>(const char*);int main() {print(42); // 使用已实例化的 print<int>(42)print(3.14); // 使用已实例化的 print<double>(3.14)print("Hello"); // 使用已实例化的 print<const char*>("Hello")return 0;
}
4、模版的特化
有时,对于某些特定类型,可能需要为模板函数提供特定的实现。模版特化的定义应以
template<>开头,并且指定具体的类型,例如:
#include <iostream>// 通用模板定义
template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}// 特化模板,针对 std::string 类型
template <>
std::string max<std::string>(const std::string &a, const std::string &b) {return (a.length() > b.length()) ? a : b;
}int main() {int intVal1 = 5, intVal2 = 10;std::string str1 = "apple", str2 = "banana";std::cout << "Max of int values: " << max(intVal1, intVal2) << std::endl;std::cout << "Longer string: " << max(str1, str2) << std::endl;return 0;
}
5、注意事项
- 对于给定的函数名,可以有非模板函数、模板函数与显示具体化模板函数以及它们的重载版本。
- 具体化优先于常规模板,而非模板函数优于具体化与常规模板。
6、总结
C++ 函数模板是一种强大的工具,它允许程序员编写与类型无关的代码,从而提高代码的可重用性和灵活性。通过模板参数,我们可以定义适用于多种数据类型的函数。此外,模板特化允许我们为特定类型提供特定的实现,从而满足特定需求。掌握函数模板的使用,将极大地提升C++编程的效率和代码质量。
相关文章:
C++ 编程基础(8)模版 | 8.2、函数模版
文章目录 一、函数模版1、声明与定义2、模版参数3、模板的实例化3.1、隐式实例化3.2、显示实例化 4、模版的特化5、注意事项6、总结 前言: C 函数模板是一种强大的特性,它允许程序员编写与类型无关的代码。通过使用模板,函数或类可以处理不同…...
Android Studio音频视频播放器课程设计
这个项目适合刚刚学习Android studio的初学者,实现音视频的基本播放功能,各项功能的页面都做的比较简单,特别适用于初学者,其特点在于本项目抛开了各种花里胡哨的制作,以最接近初学者的样式画面呈现,完全不…...
速盾:CDN是否支持屏蔽IP?
CDN(内容分发网络)是一种用于提高网站性能和可靠性的技术,通过将内容分发到距离终端用户更近的节点,减少了数据传输的延迟并提高了用户体验。在CDN中,屏蔽IP是一项重要的功能,可以帮助网站屏蔽无效或恶意请…...
机器学习—学习曲线
学习曲线是帮助理解学习算法如何工作的一种方法,作为它所拥有的经验的函数。 绘制一个符合二阶模型的学习曲线,多项式或二次函数,画出交叉验证错误Jcv,以及Jtrain训练错误,所以在这个曲线中,横轴将是Mtrai…...
在 macOS 和 Linux 中,波浪号 `~`的区别
文章目录 1、在 macOS 和 Linux 中,波浪号 ~macOS示例 Linux示例 区别总结其他注意事项示例macOSLinux 结论 2、root 用户的主目录通常是 /root解释示例切换用户使用 su 命令使用 sudo 命令 验证当前用户总结 1、在 macOS 和 Linux 中,波浪号 ~ 在 macO…...
【Java】实战:多数元素
一、题目描述 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums [3,2,3] 输出&#x…...
一文解决Latex中的eps报错eps-converted-to.pdf not found: using draft setting.
在使用Vscode配的PDFLatex编译IEEE TII的Latex模板时,出现eps文件不能转换为pdf错误,看了几十篇方法都没用,自己研究了半天终于可以正常运行了。主要原因还是Settings.JSON中的PDFLatex模块缺少:"--shell-escape", 命令…...
计算光纤色散带来的相位移动 matlab
需要注意的地方 1.以下内容纯属个人理解,很有可能不准确,请大家仅做参考 2.光速不要直接用3e8 m/s,需要用精确的2.9979.... 3.光的频率无论在真空还是光纤(介质)都是不变的,是固有属性,但是波长lambdac/f在不同的介…...
国内docker pull拉取镜像的解决方法
访问网站,查找该网站上可用的镜像源,然后替换掉下面代码中的hub-mirror.c.163.com: docker pull hub-mirror.c.163.com/library/nginx:latest 另外,进入到镜像之后,可以使用下面的命令查看操作系统版本。 lsb_releas…...
“Kafka面试攻略:核心问题与高效回答”
1,生产者发送消息的原理 发送消息的过程中,涉及到两个线程,main线程和sender线程,main线程会创建一个双端队列,main线程向双端队列发送消息,sender线程从双端队列里拉取消息,发送给Kafka Broke…...
C++ 多线程std::thread以及条件变量和互斥量的使用
前言 本文章主要介绍C11语法中std::thread的使用,以及条件变量和互斥量的使用。 std::thread介绍 构造函数 std::thread 有4个构造函数 // 默认构造函,构造一个线程对象,在这个线程中不执行任何处理动作 thread() noexcept;// 移动构造函…...
新华三H3CNE网络工程师认证—子接口技术
子接口(subinterface)是通过协议和技术将一个物理接口(interface)虚拟出来的多个逻辑接口。在VLAN虚拟局域网中,通常是一个物理接口对应一个 VLAN。在多个 VLAN 的网络上,无法使用单台路由器的一个物理接口…...
【MySQL】InnoDB内存结构
目录 InnoDB内存结构 主要组成 缓冲池 缓冲池的作用 缓冲池的结构 缓冲池中页与页之间连接方式分析 缓冲池如何组织数据 控制块初始化 页面初始化 缓冲池中页的管理 缓冲区淘汰策略 查看缓冲池信息 总结 变更缓冲区-Chang Buffer 变更缓冲区的作用 主要配置选项…...
基于大数据爬虫数据挖掘技术+Python的网络用户购物行为分析与可视化平台(源码+论文+PPT+部署文档教程等)
#1024程序员节|征文# 博主介绍:CSDN毕设辅导第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老…...
蓝桥杯每日真题 - 第19天
题目:(费用报销) 题目描述(13届 C&C B组F题) 解题思路: 1. 问题抽象 本问题可以看作一个限制条件较多的优化问题,核心是如何在金额和时间约束下选择最优方案: 动态规划是理想…...
CentOS7.9.2009的yum更换vault地窖保险库过期源,epel的archive归档源 笔记241117
CentOS7.9.2009的yum更换vault地窖保险库过期源,epel的archive归档源 笔记241117 备份 /etc/yum.repos.d 文件夹 tempUri/etc/yum.repos.d ; sudo cp -a $tempUri $tempUri.$(date %0y%0m%0d%0H%0M%0Sns%0N).bak清空 /etc/yum.repos.d 文件夹 sudo rm -rf /etc…...
Spark SQL大数据分析快速上手-完全分布模式安装
【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客 《Spark SQL大数据分析快速上手》【摘要 书评 试读】- 京东图书 大数据与数据分析_夏天又到了的博客-CSDN博客 Hadoop完全分布式环境搭建步骤-CSDN博客,前置环境安装参看此博文 完全分布模式也叫集群模式。将Spark目…...
Java面试题2024-Java基础
Java基础 1、 Java语言有哪些特点 1、简单易学、有丰富的类库 2、面向对象(Java最重要的特性,让程序耦合度更低,内聚性更高) 3、与平台无关性(JVM是Java跨平台使用的根本) 4、可靠安全 5、支持多线程 2、…...
局域网协同办公软件,2024安全的协同办公软件推荐
在2024年,随着数字化转型的深入和远程工作需求的增加,协同办公软件已成为企业提升工作效率、优化沟通流程的重要工具。 以下是一些值得推荐的安全的协同办公软件: 钉钉 功能全面:钉钉是一款综合性极强的企业级协同软件ÿ…...
osg、osgearth简介及学习环境准备
一、osg简介(三维场景图渲染与调度引擎) OSG是Open Scene Graphic 的缩写,OSG于1997年诞生于以为滑翔机爱好者之手,Don burns 为了对滑翔机的飞行进行模拟,对openGL的库进行了封装,osg的雏形就这样诞生了&…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
