Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C++模板】:开启泛型编程之门(函数模版,类模板)

【C++模板】:开启泛型编程之门(函数模版,类模板)

作者头像
用户11029137
发布于 2025-03-12 00:35:31
发布于 2025-03-12 00:35:31
19500
代码可运行
举报
文章被收录于专栏:编程学习编程学习
运行总次数:0
代码可运行

📝前言: 在上一篇文章C++内存管理中我们介绍了C++的内存管理,重点介绍了与C语言的区别,以及newdelete。这篇文章我们将介绍C++的利器——模板。 在C++编程世界里,模板是一项强大的特性,它为泛型编程奠定了坚实基础。借助模板,我们能够编写出与类型无关的通用代码,极大地提升代码复用性,减少重复劳动。接下来,让我们深入探索C++模板的奥秘。

一、函数模板

1. 函数模板概念与格式

函数模板就像一个函数家族的蓝图,该函数模板与类型无关,在使用时被参数化,编译器根据实参类型产生函数的特定类型版本。其格式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<typename T1, typename T2,......,typename Tn> 
返回值类型 函数名(参数列表){
    // 函数体
}

其中,typename是定义模板参数的关键字,也可用class替代(注意不能用struct)。例如,实现一个通用的加法函数模板:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<typename T> // 只有一
T Add(const T& left, const T& right) {
    return left + right;
}

2. 函数模板原理

函数模板本身并非真正的函数,而是编译器用于生成具体类型函数的模具。在编译阶段,编译器会依据传入的实参类型,推演并生成相应类型的函数。比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main() {
    int a = 10, b = 20;
    double c = 10.0, d = 20.0;
    Add(a, b); // 编译器将T推演为int,生成处理int类型的Add函数
    Add(c, d); // 编译器将T推演为double,生成处理double类型的Add函数
    return 0;
}

比如swap函数:

3. 函数模板实例化

当程序中调用函数模板并为类型参数指定具体类型时,编译器会根据该类型生成一个特定的函数实例。每个实例都是一个独立的函数,可以像普通函数一样被调用和执行。

  • 隐式实例化:让编译器根据实参自动推演模板参数的实际类型。不过,当实参类型无法唯一确定模板参数时会报错。例如:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main() {
    int a = 10;
    double b = 20.0;
    // Add(a, b);  // 报错,无法确定T的类型(因为在这个模板的参数列表里面只有一个参数)
    // 解决方法一:用户强制类型转换
    Add(a, (int)b);
    // 解决方法二:使用显式实例化
    Add<int>(a, b)
    return 0;
}
  • 显式实例化:在函数名后的<>中明确指定模板参数的实际类型。如:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main() {
    int a = 10;
    double b = 20.0;
    Add<int>(a, b); 
    return 0;
}

多个参数的函数模版实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>

// 函数模板,接受多个参数并打印它们
template<typename T1, typename T2, typename T3>
void printMultiple(const T1& a, const T2& b, const T3& c) {
    std::cout << "Values are: " << a << ", " << b << ", " << c << std::endl;
}

int main() {
    int intValue = 1;
    double doubleValue = 2.5;
    char charValue = 'A';

    printMultiple(intValue, doubleValue, charValue);
	// 显式实例化:printMultiple<int, double, char>(intValue, doubleValue, charValue);
    return 0;
}

4. 模板参数匹配原则

  • 一个非模板函数可以和同名函数模板共存,且函数模板能实例化为该非模板函数。
  • 调用时,若其他条件相同,优先调用非模板函数;若模板能生成更匹配的函数,则选择模板。
  • 模板函数不允许自动类型转换,普通函数可以。例如:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 专门处理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(1, 2.0); // 调用模板函数生成的更匹配版本
}

二、类模板

1. 类模板定义格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<class T1, class T2, ..., class Tn>
class 类模板名 {
    // 类内成员定义
};

以实现一个简单的栈类模板为例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
};
template<class T>
void Stack<T>::Push(const T& data) {
    // 扩容逻辑
    _array[_size] = data;
    ++_size;
}

注意:类模板中可以定义成员函数模版,但是类模板里面的成员函数不一定是函数模版。

2. 类模板实例化

类模板实例化必须是显式实例化,即:需要在类模板名字后跟<>,并将实例化类型置于其中。类模板本身不是真正的类,实例化结果才是。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main() {
    Stack<int> st1; // 实例化出处理int类型的栈
    Stack<double> st2; // 实例化出处理double类型的栈
    return 0;
}

注意:模版不建议声明和定义分离到两个文件.h和.cpp,会出现链接错误

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
数据中台OneID:详解ID-Mapping!
ID-Mapping是大数据分析中非常基本但又关键的环节,ID-Mapping通俗的说就是把几份不同来源的数据,通过各种技术手段识别为同一个对象或主题,例如同一台设备(直接),同一个用户(间接),同一家企业(间接)等等,可以形象地理解为用户画像的“拼图”过程。
大数据梦想家
2023/04/23
5.6K1
数据中台OneID:详解ID-Mapping!
《用户画像:方法论与工程化解决方案》读书笔记第3章
在画像系统搭建的过程中,数据存储的技术选型是非常重要的一项内容,不同的存储方式适用于不同的应用场景。本章主要介绍使用Hive、MySQL、HBase、Elasticsearch存储画像相关数据的应用场景及对应的解决方案。
辉哥
2022/05/13
8300
《用户画像:方法论与工程化解决方案》读书笔记第3章
数仓数据分层(ODS DWD DWS ADS)换个角度看
注意,有的公司ODS层不会做太多数据过滤处理,会放到DWD层来处理. 有的公司会在一开始时就在ODS层做数据相对精细化的过滤.这个并没有明确规定,看每个公司自己的想法和技术规范
全栈程序员站长
2022/09/13
1.9K0
基于Hive数据仓库的标签画像实战
建立用户画像首先需要建立数据仓库,用于存储用户标签数据。Hive是基于Hadoop的数据仓库工具,依赖于HDFS存储数据,提供的SQL语言可以查询存储在HDFS中的数据。开发时一般使用Hive作为数据仓库,存储标签和用户特征库等相关数据。
王知无-import_bigdata
2021/11/30
1K0
基于Hive数据仓库的标签画像实战
用户画像 | 标签数据存储之Hive真实应用
小伙伴们大家好呀,趁着年假的几天时间,我写了一篇 Elacticsearch 从0到1的“长篇大作”,现在还在排版,相信很快就会与大家见面了!关于系统学习用户画像,之前已经分享过2篇文章了,分别是《超硬核 | 一文带你入门用户画像》和《用户画像 | 开发性能调优》,收到的读者反馈还不错!本期文章,我借《用户画像方法论》一书,为大家分享在用户画像系统搭建的过程中,数据存储技术基于不同场景的使用。考虑到 篇幅的文章,我会用4篇文章分别介绍使用 Hive、MySQL、HBase、Elasticsearch 存储画像相关数据的应用场景及对应的解决方案。本期介绍的是 Hive,如果对您有所帮助,记得三连支持一下!
大数据梦想家
2021/10/22
2K0
画像标签分类及体系
本文首先介绍标签包含哪些常见实体类型以及ID类型,即标签的主体包含什么,用什么ID表达;其次详细介绍了几种标签的分类方法:按生产方式划分、按时效性划分以及按标签所属维度划分。
张叔叔讲互联网
2023/10/07
8370
画像标签分类及体系
基于Spark Graphx实现ID-Mapping
通常公司有产品矩阵,而每个产品都有自己的注册账号产生的用户ID。从公司全局,整合用户表,用户行为数据来看,确定不同产品的用户ID是相同一个人非常重要,这关系到用户行为分析,用户画像,用户数据挖掘等业务需求。
平常心
2020/10/16
5.1K0
新零售实战 | 新零售在线商城多端触达体系演进:从基础触达到智能生态的实践之旅
为了满足消费者随时随地购物的需求,在线商城的多端触达体系变得至关重要。多端触达体系涵盖了移动端的 APP、H5 页面、PWA 应用,PC 端的官网商城和后台管理系统,智能设备如 POS 机、自助收银机、AR/VR 试衣镜,以及第三方平台的微信小程序、支付宝生活号、抖音小店等。这些不同的终端和平台构成了一个庞大的网络,让企业能够全方位地触达消费者。然而,构建和优化这样一个多端触达体系并非易事,需要经历多个阶段的迭代和升级。
叶一一
2025/04/24
1950
新零售实战 | 新零售在线商城多端触达体系演进:从基础触达到智能生态的实践之旅
【软件开发规范四】《应用系统安全编码规范》
为落实《信息安全策略》的要求,有效加强应用系统安全管理,提升应用系统安全编码能力,指导开发团队有效进行应用系统安全编码,特制定本规范。
再见孙悟空_
2023/09/19
1.5K0
用户画像标签体系——从零开始搭建实时用户画像(三)
​ 用户画像的核心在于给用户“打标签”,每一个标签通常是人为规定的特征标识,用高度精炼的特征描述一类人,例如年龄、性别、兴趣偏好等,不同的标签通过结构化的数据体系整合,就可与组合出不同的用户画像。
大数据流动
2020/05/29
4.7K0
用户画像标签体系——从零开始搭建实时用户画像(三)
用户标签&营销体系的客户数据平台(CDP)建设
CDP(Customer Data Platform,客户数据平台)是由营销人管理的客户数据库,将来自不同渠道、不同场景的实时和非实时的客户数据进行采集、整合、分析和应用,以实现客户建模、设计营销活动、提升营销效率和优化客户体验的目标,从而促进企业业绩及利润的增长。接下来跟大家聊聊为什么需要建设 CDP;我们应该怎么去建设 CDP;最后是建设 CDP 我们需要做什么。
王知无-import_bigdata
2021/07/30
4.4K0
一文彻底搞懂cookie、session、token、jwt!
随着Web应用程序的出现,直接**在客户端上存储用户信息**的需求也随之出现。者背后的想象时合法的:与特定用户相关的信息都应该保存在用户的机器上。无论是登录信息、个人偏好、还是其他数据,Web应用程序提供者都需要有办法 将他们保存在客户端。对于这个问题,第一个解决方案就是cookie。
CODER-V
2023/03/02
4.8K1
一文彻底搞懂cookie、session、token、jwt!
一文读懂DDD
DDD不是架构设计方法,不能把每个设计细节具象化,DDD是一套体系,决定了其开放性,体系中可以用任何一种方法来解决这些问题,但是如果一些关键问题没有具体方案落地,可能让团队无所适从。
春哥大魔王
2019/06/02
2.5K0
神策大数据2-用户识别
神策分析使用神策ID,即events表中的user_id和users表中的id,来对每个产品的用户进行标识,即神策ID等价于这两个用户名
皮大大
2021/03/01
1.5K0
神策大数据2-用户识别
医疗系统的权限就该这样设计,稳!
前面一节介绍了码猿慢病云管理系统的多租户架构的设计,相信大家对业务也相对了解了一些,这节就来聊一聊码猿慢病云管理系统中的权限是如何设计的?
码猿技术专栏
2023/08/10
6320
医疗系统的权限就该这样设计,稳!
数据运营平台-数据采集[通俗易懂]
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说数据运营平台-数据采集[通俗易懂],希望能够帮助大家进步!!!
Java架构师必看
2022/07/06
5.3K0
数据运营平台-数据采集[通俗易懂]
一文读懂中间件
在码农的日常工作中, 经常会提到中间件,然而大家对中间件的理解并不一致,导致了一些不必要的分歧和误解。“中间件”一词被用来描述各种各样的软件产品,在不同文献中有着许多不同的中间件定义,包括操作系统(和/或网络)和应用程序之间的软件层,以及两个应用程序之间的“粘合剂”。它也被描述为一种重要的集成工具,或支持与分布式软件的模块化连接。
半吊子全栈工匠
2022/06/24
4.9K0
一文读懂中间件
一文探究数据仓库体系(2.7万字建议收藏)
数据仓库,英文名称为Data Warehouse,可简写为DW或DWH。数据仓库,是为企业所有级别的决策制定过程,提供所有类型数据支持的战略集合。它出于分析性报告和决策支持目的而创建。
肉眼品世界
2020/11/11
2K0
一文探究数据仓库体系(2.7万字建议收藏)
神策大数据用户行为分析
神策支持查看特定用户群的历史行为序列,找到提交订单行为,对此之后的行为进行人工标注,以推测后续未进行支付环节的原因
皮大大
2020/10/16
2.1K0
神策大数据用户行为分析
当金融风控遇上人工智能,众安金融的实时特征平台实践
导读:随着企业数字化转型升级,线上业务呈现多场景、多渠道、多元化的特征。数据要素价值的挖掘可谓分秒必争,业务也对数据的时效性和灵活性提出了更高的要求。在庞大分散、高并发的数据来源背景下,数据的实时处理能力成为企业提升竞争力的一大因素。今天分享的是众安金融实时特征平台实践。
NebulaGraph
2023/06/28
7710
当金融风控遇上人工智能,众安金融的实时特征平台实践
相关推荐
数据中台OneID:详解ID-Mapping!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验