C++模板初阶
C++模板初阶
- 泛型编程
- 函数模板
- 概念
- 函数模板格式
- 函数模板原理
- 函数模板的实例化
- 模板参数的匹配原则
- 类模板
- 类模板的定义格式
- 类模板的实例化
泛型编程
我们前面学习了C++的函数重载功能,那么我们如何实现一个通用的交换函数呢,比如:我传入int就是交换int,传入double就进行double类型的交换……
void Swap( int& a, int& b)
{int temp = a;a = b;b = temp;
}
void Swap(double& a, double& b)
{double temp = a;a = b;b = temp;
}
void Swap(char& a, char& b)
{char temp = a;a = b;b = temp;
}
void Swap(int*& a, int*& b)
{int* temp = a;a = b;b = temp;
}
我们可以发现尽管有了函数重载的技术,但是我们还是避免不了所有问题;我们很难写出一个通用的Swap函数,如果我们每增加一个新类型,我们就得重新写一个Swap函数,很麻烦!那么有没有什么办法让我只写一份通用的代码,所有类型都可以用呢?当然有!对于C语言的这种不足,C++在此基础上提出了泛型编程的概念:就是对于一些所有类型都可通用的代码,比如Swap这种我们在写具体实现的时候可以假装我们的数据类型是通用的,然后在对其进行处理,当我们在调用该函数的时候,编译器会自动推演出数据的具体类型,这就好比我们在写方程一样,我们先假设未知数,将未知数先当成已知,最后在解出未知数!这里自动推演数据类型的过程就相当于在解方程!
这个编写通用代码的过程就是在造模子通过给这个模子传递不同的参数类型,来确定具体的数据类型,从而获得具体类型对应的代码,生成具体类型代码的过程是由编译器来帮助我们完成的,我们无需在自己手动写了;
在C++中模板是泛型编程的基础!
模板又分为:函数模板、类模板;
函数模板
概念
函数模板代表了一个函数家族,该函数模板与类型无关,在使用参数时,由编译器根据所传参数类型自动推演函数参数的具体类型,由此产生特定类型的函数版本,这个过程,被称为实例化;
函数模板格式
template<class 类型参数名1,class 类型参数名2,…… >
返回类型 函数名(参数列表)
或者
template<typename 类型参数名1,typename 类型参数名2……>;
返回类型 函数名(参数列表)
注意:typename是用来定义模板参数的关键字,class也可以,但是struct不可以;
实例:写一个通用的交换函数:
template <typename T>
void Swap(T& a, T& b)
{T tmp = a;a = b;b = tmp;
}
函数模板原理
么如何解决上面的问题呢?大家都知道,瓦特改良蒸汽机,人类开始了工业革命,解放了生产力。机器生产淘汰掉了很多手工产品。本质是什么,重复的工作交给了机器去完成。有人给出了论调:懒人创造世界。
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器;
函数模板的实例化
用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化;
1、隐式实例化
上述Add的调用,就是隐式实例化,编译器会根据我们传递给Add的参数自动推演出类型参数的具体类型,以此来生成具体类型的交换函数来给我们用;
当然我们不能乱传递参数类型,比如:Add(a,x);
编译器在调用该Add函数的时候,根据左参数类型先推演出类型参数T为int类型,然后又根据有参数类型推演出类型参数T为double类型,那么参数类型到底具体为那个类型?这就会让编译器陷入歧义,编译器也就会报错,Add函数也就无法正确实例化!类型参数,会根据以第一次推演出的结果作为默认类型,与auto在一排的用法差不多,但是模板无法完成参数的隐式转换!
那如果我们就是要调用Add(a,x);函数应该怎么办?
有两种解决办法:
1、强转a,或强转x,就是将a,x的类型转换成一致的;
2、显示实例化;
2、显示实例化:
就是明确指定类型参数的具体类型,不需要编译器再根据参数类型自动推演了;明确指定参数的具体类型过后,编译器就会自动生成具体函数,来供调用处使用!
比如上述的Add(a,x)
我们像这样做:Add<int>(a,x);显示的指定类型参数为int,编译器就会自动生成参数类型为int的Add函数:
如果类型不匹配编译器会自动尝试隐式转换!无法完成完成隐式类型转换的编译器直接报错;
这里的隐式类型转换与上面隐式调用的类型转换不一样,这里使明确规定了类型参数的具体类型,也就是先生成了具体函数,才有的隐式类型转换;上面是根据参数类型推演类型参数的具体类型,然后再生成匹配的函数,参数不匹配,无法生成具体函数,怎么能进行隐式转换呢?
模板参数的匹配原则
1、非模板函数与函数模板同名,同时函数模板还可以实例化成非模板函数,编译器会优先调用非模板函数;
为什么会出现这种情况呢?
编译器是很聪明的,如果我们去调用函数模板时,编译器会首先根据参数类型推演出类型参数的具体类型,然后实例化出具体的Add函数来调用,你看啊,现在我明明有现成的Add函数可以用,那么我们为什么还要去实例化,再调用呢?这不是脱了裤子放屁,多此一举嘛!
那如果我们非要调用模板实例化出来的Add函数,该怎么办呢?
当然是显示调用:
2、对于非模板函数与同名函数模板,其他条件都相同,但是非模板函数的参数类型与调用处的类型不一样,编译器会根据函数模板实例化出最匹配的函数来调用:
3、对于隐式实例化函数模板,不会发生隐式类型转换;对于显示实例化函数模板,可以发生隐式类型转换;
类模板
类模板的定义格式
template<class T1,class T2,class T3,……>
class 类模板名
{
//类成员定义;
};
比如现在我们写一个栈类模板:
template <class T>
class Stack
{Stack(){int capacity = 4;_a = new T[capacity];_top = 0;_capacity = capacity;}~Stack(){delete[] _a;_top = _capacity = 0;}
private:T* _a;int _top;int _capacity;
};
类模板中的成员函数全是模板函数
然后注意此时的Stack不是具体的类,而是编译器根据被实例化的类型生成具体类的模具;
同时类模板的成员函数也可以实现在类内声明,类外定义;
只不过与我们平时写的具体的类的定义方式不太一样:
比如现在我在类内声明构造函数,类外定义构造函数:
这样我们既能定义基本数据类型为double的栈,也可以定义基本数据类型为int的栈了:
这时候或许会有读者说,我用typedef也能做到类型替换啊,可是typedef不能做到Stack<int>与Stack<double>两种栈同时存在啊,如果想要这两个栈同时存在,我们就只能再重新定义一个栈,这样很是麻烦!
同时不建议类模板的声明与函数定义分离!
类模板的实例化
类模板的实例化与函数模板的实例化不同,类模板实例化只能通过显示实例化,不能隐式实例化:
相关文章:
C++模板初阶
C模板初阶泛型编程函数模板概念函数模板格式函数模板原理函数模板的实例化模板参数的匹配原则类模板类模板的定义格式类模板的实例化泛型编程 我们前面学习了C的函数重载功能,那么我们如何实现一个通用的交换函数呢,比如:我传入int就是交换intÿ…...
文献阅读:Scaling Instruction-Finetuned Language Models
文献阅读:Scaling Instruction-Finetuned Language Models 1. 文章简介2. 实验 1. 数据集 & 模型 1. 数据集考察2. 使用模型 2. scale up对模型效果的影响3. CoT对模型效果的影响4. 不同模型下Flan的影响5. 开放接口人工标注指标 3. 结论 文献链接:…...
gpt草稿
ChatgptWhatChatGPT(全名:Chat Generative Pre-trained Transformer [2])是由OpenAI开发的一个人工智能聊天机器人程序,于2022年11月推出。该程序使用基于GPT-3.5架构的大型语言模型并通过强化学习进行训练。ChatGPT里面有两个词&…...
mysal第三次作业
1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号,不显示重复的部门号。 3、求出所有职工的人数。 4、列出最高工和最低工资。 5、列出职工的平均工资和总工资。 6、创建一个只有职工号、姓名和参加工作的新表,名为工作日期表…...
分页和mmap
文章目录一、内存分页1、基本概念2、分页机制下,虚拟地址和物理地址是如何映射的?3、快表(TLB)二、mmap基本原理和分类一、内存分页 1、基本概念 CPU并不是直接访问物理内存地址,而是通过虚拟地址空间来间接的访问物理内存地址。 页&#x…...
C++之异常处理
异常异常是面向对象语言处理错误的一种方式。当一个函数出现自己无法处理的错误时,可以抛出异常,然后输的直接或者间接调用者处理这个错误。语法捕获全部的异常try {//可能抛出异常的代码//throw异常对象 } catch(...) {//不管什么异常,都在这…...
牛客寒假集训营6 E 阿宁的生成树
E-阿宁的生成树_2023牛客寒假算法基础集训营6 (nowcoder.com)开始慢慢补牛牛的题题意:最小生成树质数距离思路:最小生成树一共就两种算法,我们考虑Prim的过程初始连通块是1,然后考虑拿1和其他的结点连边当j-i<k时边权是gcd&…...
嵌入式C基础知识(10)
C语言如何实现一个频繁使用短小函数,C如何实现?C语言可以使用宏定义实现一个短小函数,如下面例子所示。但是宏定义语句不会进行检查,并且对书写格式有过分的讲究。比如MAX和括号之间不能有空格,每个参数都要放在括号里…...
TC3xx FlexRay™ 协议控制器 (E-Ray)-01
1 FlexRay™ 协议控制器 (E-Ray) E-Ray IP 模块根据为汽车应用开发的 FlexRay™ 协议规范 v2.1 执行通信【performs communication according to the FlexRay™ 1) protocol specification v2.1】。使用最大指定时钟,比特率可以编程为高达 10 Mbit/s 的值。连接到物…...
优劣解距离法TOPSIS——清风老师
TOPSIS法是一种常用的综合评价方法,能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。 基本过程为先将原始数据矩阵统一指标类型(一般正向化处理)得到正向化的矩阵,再对正向化的矩阵进行标准化处理…...
【Unity3D】Shader常量、变量、结构体、函数
1 源码路径 Unity Shader 常量、变量、结构体、函数一般可以在 Unity Editor 安装目录下面的【Editor\Data\CGIncludes\UnityShader】目录下查看源码,主要源码文件如下: UnityCG.cgincUnityShaderUtilities.cgincUnityShaderVariables.cginc 2 Shader 常…...
LeetCode 刷题系列 -- 496. 下一个更大元素 I
nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。对于每个 0 < i < nums1.length ,找出满…...
Docker 搭建本地私有仓库
一、搭建本地私有仓库有时候使用Docker Hub这样的公共仓库可能不方便,这种情况下用户可以使用registry创建一个本地仓库供私人使用,这点跟Maven的管理类似。使用私有仓库有许多优点:1)节省网络带宽,针对于每个镜像不用…...
XML中的CDATA且mybatis中特殊字符转义
如果想看如果CDATA在mybatis的xml文件中使用的可以直接跳转。 CDATA1 XML中的CDATA1.1 为什么叫CDATA1.2 CDATA在XML中的语法1.3 CDATA在XML中的例子1.4 CDATA规则2 Mybatis中的CDATA2.1 Mybatis中使用XML转义序列转义2.2 Mybatis中使用CDATA转义2.3 mybatis中使用CDATA需注意的…...
位运算 | 1356. 根据数字二进制下 1 的数目排序
LeetCode 1356. 根据数字二进制下 1 的数目排序 给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序。如果存在多个数字二进制中 1 的数目相同,则必须将它们按照数值大小升序排列。 文章讲解https://www.programmercarl.com/1356.%…...
React Hooks之useState详解
1. 什么是Hooks? React官方简介:Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 本文中讲解的useState就是React中的其中一个Hook。 2. useState useState 通过在函数组件里调用它来满足给组件添…...
选购交换机的参数依据和主要的参数指标详解
如何选购交换机?用什么交换机?在选购交换机时交换机的优劣无疑十分的重要,而交换机的优劣要从总体构架、性能和功能三方面入手。交换机选购时。性能方面除了要满足RFC2544建议的基本标准,即吞吐量、时延、丢包率外,随着…...
Connext DDS属性配置参考大全(1)
介绍属性QoS策略存储名称/值(字符串)对,可用于配置Connext DDS的某些参数,这些参数未通过正式的QoS策略公开。 属性QoS策略存储实体的名称/值对。名称和值都是字符串。在核心库用户手册的“Property QosPolicy(DDS Extension)”部分中找到有关RTI Connext DDS属性QoS的更…...
Docker安全
容器的安全性问题的根源在于容器和宿主机共享内核。如果容器里的应用导致Linux内核崩溃,那么整个系统可能都会崩溃。 与虚拟机是不同的,虚拟机并没有与主机共享内核,虚拟机崩溃一般不会导致宿主机崩溃 一、Docker 容器与虚拟机的区别 1、隔…...
刷题记录:牛客NC20279[SCOI2010]序列操作
传送门:牛客 题目描述: lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全…...
Fluent Python 笔记 第 6 章 使用一等函数实现设计模式
虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用。1996 年,Peter Norvig 在题为“Design Patterns in Dynamic Languages”(http://norvig.com/design- patterns/)的演讲中指出,Gamma 等人合著的《设计模式:可复用面…...
windbg-应用层实时调试
调试符号windbg使用一个或多个目录来存放符号条件,并使用环境变量_NT_SYMBOL_PATH来指向这些环境变量的位置,对操作系统内部模块的符号文件,一般用http://msdl.microsoft.com/download/symbols配置如下:SRV*C:\Symbols*http://msd…...
【Python语言基础】——Python NumPy 数组索引
Python语言基础——Python NumPy 数组索引 文章目录 Python语言基础——Python NumPy 数组索引一、Python NumPy 数组索引一、Python NumPy 数组索引 访问数组元素 数组索引等同于访问数组元素。 您可以通过引用其索引号来访问数组元素。 NumPy 数组中的索引以 0 开头,这意味…...
MWORKS--MoHub介绍
MWORKS--MoHub介绍1 介绍1.1 简介1.2 功能特征2 快速上手2.1 进入工作台2.2 新建仓库并进入建模空间2.3 建模进入建模工作空间加载模型库新建模型2.4 仿真2.5 后处理曲线、动画2.6 查看模型信息3 使用手册参考1 介绍 1.1 简介 MWORKS.MoHub 支持工业知识、经验、数据的模型化…...
Netty零拷贝机制
Netty零拷贝机制一:用户空间与内核空间二:传统IO流程三:零拷贝常见的实现方式1. mmap write2. sendfile四:Java中零拷贝五:Netty 中如何实现零拷贝1. CompositeByteBuf 实现零拷贝2. wrap 实现零拷贝3. slice 实现零拷…...
C++:提高篇: 栈-寄存器和函数状态:windows X86-64寄存器介绍
寄存器1、什么是寄存器2、寄存器分类3、windows X86寄存器命名规则4、寄存器相关术语5、寄存器分类5.1、RAX(accumulator register)5.2、RBX(Base register)5.3、RDX(Data register)5.4、RCX(counter register)5.5、RSI(Source index)5.6、RDI(Destination index)5.7、RSP(stac…...
MyBatis-Plus入门案例
MyBatis-Plus入门案例一、MyBatis-Plus简介1、简介2、特性3、支持数据库4、框架结构5、代码及文档地址二、入门案例1、开发环境2、建库建表3、创建Spring Boot工程a>初始化工程b>引入依赖4、编写代码a>配置application.yml 或者 application.propertiesb>添加实体c…...
适用于 Windows 11/10/8/7 的 10 大数据恢复软件分享
适用于 Windows 11/10/8/7 的 最佳数据恢复软件综述。选择首选的专业数据/文件恢复软件,轻松恢复丢失的数据或删除的照片、视频等文件、SSD、外接硬盘、USB、SD卡等存储设备中的文件等。流行的sh流行的数据恢复软件也包括在内。 10 大数据恢复软件分享 为了帮助您恢…...
在线支付系列【23】支付宝支付接入指南
有道无术,术尚可求,有术无道,止于术。 文章目录前言接入指南1. 创建应用2. 绑定应用3. 配置密钥4. 上线应用5. 开通产品沙箱环境开发前准备(沙箱环境)1. 获取参数、秘钥、证书2. 下载支付宝客户端3. 案例演示前言 在之…...
linux系统常用命令
目录 一、系统介绍 二、Linux常用命令 1、Linux命令格式 2、文件目录操作命令:ls 3、文件目录操作命令:cd 4、文件目录操作命令:cat 5、文件目录操作命令:more 6、文件目录操作命令:tail 7、创建文件命令&…...
做标签网站/理发培训专业学校
docker images|grep none|awk {print $3}|xargs docker rmi 转载于:https://www.cnblogs.com/jiuchongxiao/p/9597069.html...
做淘客网站用备案吗/交换链接营销的典型案例
1.jboss和cxf不兼容,最好集成axis,需要在WEB-INF下增加下面文件,文件配置 <?xml version"1.0" encoding"UTF-8"?> <deployment xmlns"http://xml.apache.org/axis/wsdd/" xmlns:java"http://x…...
做网站需要会什么条件/北京环球影城每日客流怎么看
1.Project GNU 简介 Project GNU 的起源,来自十年前, Richard Stallman, 目前为 Project GNU 的计划主持人, 在网路讨论区的一篇文章( http://www.cs.pdx.edu/~trent/gnu/begin, 10 years ago on Internet ࿰…...
旅游网站哪个做的好/网络营销和传统营销的区别和联系
MySQL组合两个表SQL架构表1: Person表2: Address编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:题解方式1方式2SQL架构 Create table Person (PersonId int, FirstName varc…...
英语培训建设网站方案/石家庄网络seo推广
原文:How To Make A UIViewController Transition Animation Like in the Ping App 作者:Luke Parham 译者:kmyhy 更新说明:本教程由 Luke Parhm 更新至 Xcode 9/Swift 4。原文作者是 Rounak Jain。 不久前,匿名社交…...
哪些网站可以做旅游/网络营销计划书怎么写
本文和大家重点讨论一下CSS网页布局中文字排版九大技巧,主要包括如何设定字体、颜色、大小、段落空白,首字下沉、首行缩进。***讲一些常用的web页面中文排版,比如中文字的截断、固定宽度词内折行(word-wrap和word-break)等等。CSS网页布局中文…...