C++的模板简介
文章目录
- 一、前言
- 二、函数模板(Function Template)
- 三、类模板(Class Template)
- 四、变参模板(Variadic Template)
- 五、模板的递归与元编程
- 六、模板的局限与陷阱
- 七、常用模板的实例
- 八、C++20 的概念(Concepts)
- 九、总结
一、前言
C++的模板(Template)是C++中一种强大的特性,它允许编写泛型程序,即编写不依赖于具体类型的代码。模板提供了一种机制,可以在编译时生成针对不同数据类型的代码,而不需要重复编写相同逻辑的代码。这种机制使得代码更加灵活和可重用。
二、函数模板(Function Template)
函数模板允许我们编写与具体类型无关的函数,从而使得函数能够处理不同的数据类型。函数模板的语法格式如下:
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表)
{// 函数体
}
注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}int main() {int x = 10, y = 20;double a = 5.5, b = 2.3;std::cout << max(x, y) << std::endl; // 输出 20std::cout << max(a, b) << std::endl; // 输出 5.5return 0;
}
在这里,typename T 表示模板参数T,它是一个占位符,表示函数中可以使用任意类型。当我们调用这个函数时,编译器会根据传递的参数类型自动推导出T的具体类型。
- 模板类型参数与非类型模板参数
除了类型参数外,C++还支持非类型模板参数。非类型模板参数通常是一个整数或指针值,可以在编译时确定。例如:
template <typename T, int size>
T arraySum(T (&arr)[size]) {T sum = 0;for (int i = 0; i < size; ++i) {sum += arr[i];}return sum;
}
在这个例子中,size 是一个非类型模板参数,表示数组的大小。
- 显式指定模板参数
虽然编译器通常可以推导出模板参数,但也可以显式地指定它们:
int a = max<int>(3, 7);
三、类模板(Class Template)
类模板允许定义一个通用的类,然后可以用不同的数据类型来实例化该类。典型的例子是标准库中的 std::vector 类,它是一个类模板,可以用来存储任意类型的元素。它的语法格式跟类模板类型,下面是一个简单的类模板示例:
template <typename T>
class Pair {
public:Pair(T first, T second) : first_(first), second_(second) {}T getFirst() const { return first_; }T getSecond() const { return second_; }private:T first_, second_;
};int main() {Pair<int> intPair(1, 2);Pair<std::string> stringPair("hello", "world");std::cout << intPair.getFirst() << ", " << intPair.getSecond() << std::endl; // 输出 1, 2std::cout << stringPair.getFirst() << ", " << stringPair.getSecond() << std::endl; // 输出 hello, worldreturn 0;
}
- 模板特化(Template Specialization)
模板特化允许我们为特定类型提供模板的特殊实现。模板特化有两种形式:全特化和部分特化。全特化是为模板的特定类型提供完全不同的实现,下面这个例子实例化Pair< bool >时就会调用特化实现而不是通用实现:
template <typename T>
class Pair {
public:Pair(T first, T second) : first_(first), second_(second) {}T getFirst() const { return first_; }T getSecond() const { return second_; }private:T first_, second_;
};template <>
class Pair<bool> {
public:Pair(bool first, bool second) : bits((first ? 1 : 0) | (second ? 2 : 0)) {}bool getFirst() const { return bits & 1; }bool getSecond() const { return bits & 2; }private:int bits;
};
部分特化只适用于类模板,而不是函数模板,它允许为一部分模板参数提供特定实现:
template <typename T, typename U>
class Pair {
public:Pair(T first, U second) : first_(first), second_(second) {}void print() { std::cout << first_ << ", " << second_ << std::endl; }
private:T first_;U second_;
};// 部分特化版本,针对相同类型的 Pair
template <typename T>
class Pair<T, T> {
public:Pair(T first, T second) : first_(first), second_(second) {}void print() { std::cout << "Matching types: " << first_ << ", " << second_ << std::endl; }
private:T first_;T second_;
};
在这个例子中,当 Pair 的两个模板参数类型相同时,编译器会选择部分特化版本,而不是通用版本。
四、变参模板(Variadic Template)
C++11 引入了变参模板,允许模板接受可变数量的模板参数。这对处理不定数量的参数或类型非常有用。
template<typename... Args>
void print(Args... args) {(std::cout << ... << args) << std::endl;
}
在这个例子中,print函数可以接受任意数量的参数,并将它们打印出来。
五、模板的递归与元编程
模板递归和元编程是一种高级用法,允许在编译时进行复杂的计算和逻辑处理。典型的例子是计算编译时的斐波那契数列:
template<int N>
struct Fibonacci {static const int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
};template<>
struct Fibonacci<1> {static const int value = 1;
};template<>
struct Fibonacci<0> {static const int value = 0;
};
这种编译期计算被称为模板元编程(Template Metaprogramming),用于在编译期执行逻辑判断和计算。
六、模板的局限与陷阱
编译时间: 模板实例化会增加编译时间,尤其是对于大型代码库。
代码膨胀: 模板实例化会导致二进制文件膨胀,因为每种类型的实例化都会生成独立的代码。
错误信息复杂: 当模板代码出错时,编译器产生的错误信息通常较为复杂且难以理解。
七、常用模板的实例
STL 是 C++ 标准库的一部分,其中包含了大量的模板,如 std::vector, std::map, std::set 等。这些模板类使得开发者能够方便地使用各种数据结构和算法,而不必为每种类型单独实现。
八、C++20 的概念(Concepts)
C++20 引入了概念(Concepts),使得模板的类型约束更加明确。概念是一种用于限制模板参数的特性,可以显著提高模板代码的可读性和可维护性。
template <typename T>
concept Addable = requires(T a, T b) {{ a + b } -> std::convertible_to<T>;
};template <Addable T>
T add(T a, T b) {return a + b;
}
通过引入概念,编译器可以更早地检测出不满足条件的模板参数,从而减少复杂的编译错误信息。
九、总结
C++模板是一种功能强大且灵活的机制,能够极大地提高代码的复用性和类型安全性。模板的学习曲线较为陡峭,但一旦掌握,它将成为编写高效、通用代码的利器。C++20 的概念进一步增强了模板的表达能力,使得模板编程更加直观和强大。
相关文章:
C++的模板简介
文章目录 一、前言二、函数模板(Function Template)三、类模板(Class Template)四、变参模板(Variadic Template)五、模板的递归与元编程六、模板的局限与陷阱七、常用模板的实例八、C20 的概念(…...
树莓派5 笔记25:第一次启动与配置树莓派5_8G
今日继续学习树莓派5 8G:(Raspberry Pi,简称RPi或RasPi) 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 与 python 版本如下: 今日购得了树莓派5_8G版本,性能是同运…...
Melittin 蜂毒肽;GIGAVLKVLT TGLPALISWI KRKRQQ
【Melittin 蜂毒肽 简介】 蜂毒肽(Melittin)是蜜蜂毒液中的主要活性成分,由26个氨基酸组成,具有强碱性,易溶于水,是已知抗炎性最强的物质之一。蜂毒肽具有多种生物学、药理学和毒理学作用,包括…...
day32
更新源 cd /etc/apt/ sudo cp sources.list sources.list.save 将原镜像备份 sudo vim sources.list 将原镜像修改成阿里源/清华源,如所述 阿里源 deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiver…...
【clickhouse】 使用 SQLAlchemy 连接 ClickHouse 数据库的完整指南
我听见有人猜 你是敌人潜伏的内线 和你相知多年 我确信对你的了解 你舍命救我画面 一一在眼前浮现 司空见惯了鲜血 你忘记你本是娇娆的红颜 感觉你我彼此都那么依恋 🎵 许嵩《内线》 ClickHouse 是一款非常高效的开源列式数据库,因…...
按键收集单击,双击和长按
按键收集单击,双击和长按 引言 在我们生活中, 按键是必不可少的, 不同的电器, 有不同的按键, 但是按键总有不够用的时候, 那么给与一个按键赋予不同的功能,就必不可少了. 一个按键可以通过按下的时间长短和频次, 来定义其类型。 一次按键收集, 都是在一个按键收集周…...
进程的异常终止
进程的异常终止 进程收到了某些信号,他杀 进程自己调用abort函数,产生了SIGABRT(6)信号,自杀 进程的最后一个线程收到了"取消"操作,并且做出响应 如果进程是异常结束的,atexit\on_exit它们事先注册的遗言…...
并发编程 | Future是如何优化程序性能
在初识Future一文中介绍了Future的核心方法。本文中接着介绍如何用Future优化我们的程序性能。 在此之前,有必要介绍Future接口的一个实现类FutureTask。 FutureTask介绍 FutureTask继承结构 首先我们看一下FutureTask的继承结构: public class Futur…...
Oracle笔记
一、 如何解决 sqlplus 无法使用退格键和方向键 .bashrc 中添加如下内容,解决 退格键 stty erase ^h 安装 rlwap 后,执行如下命令可解决 方向键 rlwap sqlplus 二、 都有哪些备份数据到工具 三、 谈谈 你对 oracle 中实例和数据库的理解 数据库是一…...
LVS+Keepalived 双机热备
LVSKeepalived 双机热备 Keepalived案例分析Keepalived工具介绍Keepalived工具介绍一、功能特点 一、理解Keepalived实现原理实验报告资源列表一、安装keepalived以及ipvsadm Keepalived案例分析 企业应用中,单台服务器承担应用存在单点故障的危险单点故障一旦发生…...
Web Image scr图片从后端API获取基本实现
因系统开发中需求,会有页面显示图片直接从后端获取后显示,代码如下: 后端: /*** 获取图片流* param response* param fileName*/RequestMapping(value"getImgStream",method RequestMethod.GET)public void getImgStr…...
2024音频剪辑指南:探索四大高效工具!
音频剪辑不仅仅是技术活,更是一种艺术创作,它能够让声音更加生动、更具感染力。今天,我们就来探索几款优秀的音频剪辑工具。 福昕音频剪辑 链接:www.pdf365.cn/foxit-clip/ 福昕音频剪辑是一款界面简洁、操作直观的音频编辑软件…...
“CSS”第一步——WEB开发系列13
CSS (Cascading Style Sheets,层叠样式表),是一种用来为结构化文档(如 HTML 文档或 XML 应用)添加样式(字体、间距和颜色等)的计算机语言,CSS 文件扩展名为 .css。 一、什么是 CSS&a…...
IEEE802网络协议和标准
IEEE802网络协议和标准 802委员会IEEE 802介绍现有标准 IEEE 802.3介绍物理媒介类型MAC子层与LLC子层主要内容通讯标准POE供电标准802.3af、802.3at、802.3btIEEE802.3af的工作过程:IEEE802.3af主要供电参数:IEEE802.3af的分级参数:为什么会有…...
vulnhub靶机 DC-9(渗透测试详解)
一、靶机信息收集 1、靶机下载 https://download.vulnhub.com/dc/DC-9.zip 2、靶机IP扫描 3、探测靶机主机、端口、服务版本信息 4、靶机目录扫描 二、web渗透测试 1、访问靶机IP 查看页面功能点,发现一个搜索框和登录框 2、测试一下是否存在sql注入 查看当前数…...
javaweb的新能源充电系统pf
TOC springboot339javaweb的新能源充电系统pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现,改变了几千年以来人们的生活,不仅仅是生活物资的丰富,还有精神层次的丰富。在互联网诞生之前,地域位置往往是人们思想上不可跨域…...
如何在桌面同时展示多个窗口
一、实现2分屏显示 win箭头 二、实现3分屏显示 1. 在实现2分屏显示的基础上,再次点击箭头图标,这次选择屏幕的上方或下方。 2. 点击后,第三个窗口将会出现在你选择的区域。现在,你可以在三个窗口之间自由切换,提高工…...
The Sandbox 游戏制作教程(第 5 部分):创建基于分类的系统
欢迎回到我们的系列,我们将记录 The Sandbox Game Maker 的 “On-Equip”(装备)功能的多种用途。 如果你刚加入 The Sandbox,装备功能是 “可收集组件”(Collectable Component)中的一个多功能工具&#x…...
HTML浏览器缓存(Browser Cache)
介绍: 浏览器缓存是Web缓存中最直接、最常见的一种形式。当浏览器首次请求某个资源时,如果服务器响应中包含了缓存控制指令(如Cache-Control、Expires等),浏览器就会将这些资源存储在本地缓存中。后续请求相同资源时&a…...
短剧APP系统,推动短剧市场发展
近年来,短剧作为一直火爆的新兴行业,凭借着剧情进奏、爽、时长短等优势,深受大众欢迎,成为了大众碎片化时间的解压神器。 目前,随着短剧市场的快速发展,各个类型的短剧层出不穷,也推动了短剧AP…...
Vue 3.4+ 实验性/新特性深度实战(2026版)
一、背景:从“稳定”到“极致体验”截至 2026 年,Vue 3.4 与 3.5 已全面普及,但许多能显著降低心智负担的特性(如 defineModel)在早期被标记为“实验性”,或仅在 3.5 才完全稳定。如果你还在写“Pr…...
FireRedASR Pro在微信小程序开发中的应用:实时语音输入与转写
FireRedASR Pro在微信小程序开发中的应用:实时语音输入与转写 不知道你有没有这样的经历:用手机打字回复长消息时,手指按得发酸;或者在线听课时,想快速记下老师的重点,手速却跟不上语速。在移动优先的今天…...
像素风AI工具体验:像素史诗智识终端,让研究变得有趣又高效
像素风AI工具体验:像素史诗智识终端,让研究变得有趣又高效 1. 引言:当科研遇上像素冒险 想象一下:你是一位勇者,站在像素风格的城堡前,准备开始一场史诗般的冒险。但这次,你的武器不是剑与盾&…...
5个颠覆认知的无损视频处理能力:LosslessCut全解析
5个颠覆认知的无损视频处理能力:LosslessCut全解析 【免费下载链接】lossless-cut The swiss army knife of lossless video/audio editing 项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut 在数字内容创作爆炸的时代,视频处理已成为创…...
CefFlashBrowser:终极Flash浏览器解决方案,轻松玩转经典Flash游戏与课件
CefFlashBrowser:终极Flash浏览器解决方案,轻松玩转经典Flash游戏与课件 【免费下载链接】CefFlashBrowser Flash浏览器 / Flash Browser 项目地址: https://gitcode.com/gh_mirrors/ce/CefFlashBrowser 你是否还在为无法打开珍藏的Flash游戏而烦…...
DanKoe 视频笔记:原创思维指南:如何进行原创思考
在本教程中,我们将学习如何摆脱思维定式,培养真正的原创思考能力。我们将探讨为何独立思考如此困难,并提供一套实用的方法来帮助你形成自己的观点、连接不同领域的知识,并最终创造出有价值的内容。 概述 每个人都希望成为一个原创…...
Neeshck-Z-lmage_LYX_v2多场景落地:LoRA动态加载赋能数字人直播背景实时生成系统
Neeshck-Z-lmage_LYX_v2多场景落地:LoRA动态加载赋能数字人直播背景实时生成系统 1. 项目简介:一个专为本地绘画优化的轻量级工具 如果你对AI绘画感兴趣,特别是想体验国产的Z-Image文生图模型,但又被复杂的部署流程、繁琐的参数…...
OFA模型在零售行业的视觉问答应用案例
OFA模型在零售行业的视觉问答应用案例 1. 引言 走进任何一家现代零售商店,你都会看到成千上万的商品整齐地陈列在货架上。但对于店员来说,要快速准确地回答"这个品牌的洗发水有没有无硅油版本?"或者"这款饼干是否含有坚果成…...
Qwen2.5-VL视觉定位模型支持多目标检测:一句话同时定位‘人和汽车’,效果惊艳
Qwen2.5-VL视觉定位模型支持多目标检测:一句话同时定位"人和汽车",效果惊艳 1. 视觉定位技术的新突破 在计算机视觉领域,视觉定位(Visual Grounding)技术正经历着革命性的进步。传统的目标检测方法需要预先…...
Copilot 插入广告引担忧,AI 工具商业化边界受考
Copilot 拉取请求中惊现广告插入团队成员使用 Copilot 纠正拉取请求(PR)中的拼写错误时,出现了令人意想不到的情况。Copilot 不仅修改了 PR 描述,还插入了它自身以及 Raycast 的广告。这一行为引发了用户的强烈反应,有…...
