c++:模板

1.泛型编程 

 在认识模板之前,我们首先要认识泛型编程

泛型编程是一种编程范式,它使得算法和数据结构能够独立于特定数据类型进行设计和实现。通过使用泛型,开发者可以编写一次代码,然后在不同的数据类型上进行重用,从而提高代码的灵活性和可维护性

编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础

若不使用泛型编程,写实现变量的值交换的函数:

void Swap(int& a, int& b)  //整形
{
    int tmp = a;
    a = b;
    b = tmp;
}
void Swap(float& a, float& b)  //浮点型
{
    float tmp = a;
    a = b;
    b = tmp;
}
void Swap(char& a, char& b) //字符型
{
    char tmp = a;
    a = b;
    b = tmp;
}

代码的关键部分非常相似,代码很冗余,使用泛型编程可以很好的解决这个问题 

 template<typename T1>  //这是一个函数模板,可以完成上面三个函数的功能 
void Swap(T1& a, T1& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}

泛型编程就像是一个模子,让编译器根据不同类型,生成不同的代码 ,从而实现对应的功能                

 2.函数模板

1.函数模板概念 

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生 函数的特定类型版本 

函数模板是一种用于生成函数的工具,通过模板定义可以创建适用于多种数据类型的函数

2.函数模板格式 

template<typename T1, typename T2 ......> 

返回值类型   函数名(参数列表)

{

    //代码块

}

 例如上面交换两个变量的值的例子

template<typename T1>

void Swap(T1& a, T1& b)
{
    T tmp = a;
    a = b;
    b = tmp;

typename是用来定义模板参数关键字,也可以使用class 

3.函数模板原理 

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。 所以其实模板就是将本来应该我们做的重复的事情交给了编译器 

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应 类型的函数以供调用。

4.函数模板的实例化 

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化显式实例化 

1.隐式实例化:让编译器根据实参推演模板参数的实际类型

template<class T>
T Add(const T& a, const T& b)
{
    return a + b;
}
int main()
{
    int a1 = 10;
    int a2 = 5;
    float b1 = 10.5;
    float b2 = 4.0;

    Add(a1, a2);
    Add(b1, b2);

    Add(a1, b1);  //编译器无法确定T是整形还是浮点型而报错
    Add(a1, (int)b1);  //可以将b1强制转换成int类型
    return 0;
}

2.显式实例化:在函数名后的<>中指定模板参数的实际类型 

int main(void)
{
    int a = 10;
    double b = 20.0;
    // 显式实例化
    Add<int>(a, b);  //显示为int类型
    return 0;

 5.模板函数匹配原则

1.一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数 

//专门处理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版本

就是说,如果我们已经定义了一个函数模板,又有一个非模板函数,在调用一个函数时,非模板函数与模板函数都适配,优先选择非模板函数,如果模板可以产生一个具有更好匹配的函数, 那么将选择模板函数

显示实例化调用,则调用模板函数 (模板函数是指编译器通过函数模板生成的一个函数)

// 专门处理int的加法函数
int Add(int left, int right)
{
    return left + right;
}

// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
    return left + right;
}
void Test()
{
    Add(1, 2);        // 与非函数模板类型完全匹配,不需要函数模板实例化
    Add(1, 2.0);    // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
}

还需要注意的一点是: 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

3.类模板 

1.类模板的定义格式 

template<class T1, class T2, ..., class Tn>
class 类模板名
{
    // 类内成员定义
}; 

例如下面这个例子: 

// 类模版
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;
};

// 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误
template<class T>
void Stack<T>::Push(const T& data)
{
    // 扩容
    _array[_size] = data;
    ++_size;
}


int main()
{
    Stack<int> st1;            // int
    Stack<double> st2;     // double
    return 0;
}

2.类模板的实例化 

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>然后将实例化的 类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类

// Stack是类名,Stack<int>才是类型

Stack<int>  st1;           // int

Stack<double>  st2;    // double

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/19003.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux下安装配置redis详细教程,并配置哨兵模式,redis配置文件中文详解

redis版本为redis-3.2.12&#xff0c;使用工具将安装包上传到data目录。 redis.jpeg 在data目录下创建文件夹redis&#xff0c;将redis安装在此目录。 第一步&#xff1a;解压。 cd data tar -zxvf redis-3.2.12.tar.gz第二步&#xff1a;安装&#xff0c;PREFIX/data/redis用…

R语言数据分析案例45-全国汽车销售数据分析(可视化与回归分析)

一、研究背景 随着经济的发展和人们生活水平的提高&#xff0c;汽车已经成为人们日常生活中不可或缺的交通工具之一。汽车市场的规模不断扩大&#xff0c;同时竞争也日益激烈。对于汽车制造商和经销商来说&#xff0c;深入了解汽车销售数据背后的规律和影响因素&#xff0c;对…

Java 网络编程:Socket 与网络通信

1 引言 在古代&#xff0c;由于通信不便利&#xff0c;人们利用鸽子的飞行能力和方向辨识能力&#xff0c;驯化鸽子进行消息传递&#xff0c;即所谓的“飞鸽传书”。在现代计算机网络中&#xff0c;套接字&#xff08;Socket&#xff09;扮演了类似的角色。套接字是应用程序通…

编程之路,从0开始:结构体详解

目录 前言 正文 1、结构体引入 2、结构体的声明 3、typedef 4、结构体的匿名声明 5、结构的自引用 &#xff08;1&#xff09;链表 &#xff08;2&#xff09;自引用 6、结构体内存对齐 &#xff08;1&#xff09;对齐规则 &#xff08;2&#xff09;题目 &#x…

Flink监控checkpoint

Flink的web界面提供了一个选项卡来监控作业的检查点。这些统计信息在任务终止后也可用。有四个选项卡可以显示关于检查点的信息:概述(Overview)、历史(History)、摘要(Summary)和配置(Configuration)。下面依次来看这几个选项。 Overview Tab Overview选项卡列出了以…

04-转录组下游分析-标准化、聚类、差异分析

准备工作 1.数据标准化 标准化前需要进行数据预处理 过滤低表达的基因&#xff0c;并检查是否有异常样本 以下是常见的几种过滤方式&#xff08;过滤的标准都可以自己调整&#xff09; 1&#xff1a;在至少在75%的样本中都表达的基因&#xff08;表达是指在某个样本中count值…

常见网络厂商设备默认用户名/密码大全

常见网络厂商的默认用户名/密码 01 思科 (Cisco) 设备类型&#xff1a;路由器、交换机、防火墙、无线控制器 默认用户名&#xff1a;cisco 默认密码&#xff1a;cisco 设备类型&#xff1a;网管型交换机 默认用户名&#xff1a;admin 默认密码&#xff1a;admin 02 华…

Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系

一.什么是Spring&#xff1f;它解决了什么问题&#xff1f; 1.1什么是Spring&#xff1f; Spring&#xff0c;一般指代的是Spring Framework 它是一个开源的应用程序框架&#xff0c;提供了一个简易的开发方式&#xff0c;通过这种开发方式&#xff0c;将避免那些可能致使代码…

【热门主题】000055 网络安全:构筑数字时代的坚固防线

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

鸿蒙中位置权限和相机权限

1.module.json5中添加相关权限和string.json中配置信息 2. import { hilog } from kit.PerformanceAnalysisKit; import { TAG } from ohos/hypium/src/main/Constant; import { bundleManager, common } from kit.AbilityKit; import { abilityAccessCtrl } from kit.Ability…

2024.6使用 UMLS 集成的基于 CNN 的文本索引增强医学图像检索

Enhancing Medical Image Retrieval with UMLS-Integrated CNN-Based Text Indexing 问题 医疗图像检索中&#xff0c;图像与相关文本的一致性问题&#xff0c;如患者有病症但影像可能无明显异常&#xff0c;影响图像检索系统准确性。传统的基于文本的医学图像检索&#xff0…

H.264/H.265播放器EasyPlayer.js网页直播/点播播放器关于播放的时候就有声音

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS、WEBRTC、FMP4视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、Mp3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方…

Redis 的代理类注入失败,连不上 redis

在测试 redis 是否成功连接时&#xff0c;发现 bean 没有被创建成功&#xff0c;导致报错 根据报错提示&#xff0c;需要我们添加依赖&#xff1a; <dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>&l…

Prometheus结合K8s(一)搭建

公司之前K8s集群没有监控&#xff0c;top查看机器cpu使用率很高&#xff0c;为了监控pod的cpu和内存&#xff0c;集群外的mysql资源&#xff0c;初步搭建了Prometheus监控系统 提前准备镜像 docker.io/grafana/grafana 10.4.4 docker.io/prom/prometheus v2.47.2 docker.io/…

Vscode/Code-server无网环境安装通义灵码

Date: 2024-11-18 参考材料&#xff1a;https://help.aliyun.com/zh/lingma/user-guide/individual-edition-login-tongyi-lingma?spma2c4g.11186623.0.i0 1. 首先在vscode/code-server插件市场中安装通义插件&#xff0c;这步就不细说了。如果服务器没网&#xff0c;会问你要…

【划分型DP-约束划分个数】力扣813. 最大平均值和的分组

给定数组 nums 和一个整数 k 。我们将给定的数组 nums 分成 最多 k 个非空子数组&#xff0c;且数组内部是连续的 。 分数 由每个子数组内的平均值的总和构成。 注意我们必须使用 nums 数组中的每一个数进行分组&#xff0c;并且分数不一定需要是整数。 返回我们所能得到的最…

IDEA:2023版远程服务器debug

很简单&#xff0c;但是很多文档没有写清楚&#xff0c;wocao 一、首先新建一个远程jvm 二、配置 三、把上面的参数复制出来 -agentlib:jdwptransportdt_socket,servery,suspendn,address5005 四、然后把这串代码放到服务器中 /www/server/java/jdk1.8.0_371/bin/java -agentl…

centos安装jenkins

本机使用虚拟机centos 7.9.2009 安装gitlab&#xff0c;本机的虚拟机ip地址是 192.168.60.151&#xff0c; 步骤记录如下 1、下载jenkins&#xff0c;安装jenkins之前需要安装jdk jdk和jenkins的版本对应关系参考&#xff1a;Redhat Jenkins Packages Index of /redhat-stable…

蜀道山CTF<最高的山最长的河>出题记录

出这道题的最开始感觉就是,因为现在逆向的形式好多,我最开始学习的时候,经常因为很多工具,或者手段完全不知道,就很懵逼,很多师傅都出了各种类型的,我就想着给以前的"自己"出一道正常exe,慢慢调的题,为了不那么简单,我就选择了C(究极混淆,可能比rust好点),让大家无聊…

中伟视界:AI智能分析算法如何针对非煤矿山的特定需求,提供定制化的安全生产解决方案

非煤矿山智能化改造&#xff0c;除了政策文件&#xff0c;上级监管单位需要安装的AI智能分析算法功能之外的&#xff0c;矿方真正关心的&#xff0c;能解决矿方安全生产隐患的AI智能分析算法功能有哪些呢&#xff1f; 经过与矿方的现场交流沟通&#xff0c;收集第一现场人员对安…