C/C++ 深入浅出C++模板(上)

news2024/11/28 20:50:01

  不知道你是否思考过一个问题,那就是为什么C++有丰富的库,而C语言却没有?比如说C++有STL库,线程库等。其实一个很重要的因素就是因为C++引入了泛型编程这个概念,也就是我们熟悉的模板。今天我们就一起来深入理解什么是泛型编程,以及模板的概念,学完这些之后,我们就能够更好得理解C++这门语言。

在这里插入图片描述
                              连峰去天不盈尺 枯松倒挂倚绝壁,飞湍瀑流争喧豗。

这里写目录标题

  • 一、 泛型编程
  • 二、 函数模板
  • 三、类模板
  • 四、非类型模板参数
  • 总结和思维导图

提示:以下是本篇文章正文内容,下面案例可供参考


一、 泛型编程

1.1概念引入
  我们如何实现一个通用的逆序函数?

void Reverse(int* left, int* right)
{
    while (left < right)
    {
        int tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
void Reverse(double* left, double* right)
{
    while (left < right)
    {
        double tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
void Reverse(char* left, char* right)
{
    while (left < right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}

运用我们之前学习过的知识,我们知道使用函数重载虽然可以实现,但是有一下几个不好的地方:
1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增
加对应的函数
2. 代码的可维护性比较低,一个出错可能所有的重载均出错。

能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
其中,模板包括函数模板和类模板。


二、 函数模板

2.1概念

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

2.2函数模板格式

template<typename T1, typename T2,…,typename Tn>
返回值类型 函数名(参数列表){}

实现一个通用的逆序函数。代码示例:

template<class T>
void Reverse(T* left, T* right)
{
    while (left < right)
    {
        T tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}

注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)


2.3函数模板的原理

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

在这里插入图片描述
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。


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

  1. 隐式实例化:让编译器根据实参推演模板参数的实际类型
    代码示例:
template<class T>
void Reverse(T* left, T* right)
{
    while (left < right)
    {
        T tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
int main()
{
    int a[100] = { 0 };
    char b[100];
    double c[100] = { 0.0 };
    for (int i = 1; i <= 10; i++)
    {
        a[i] = i;
        b[i] = 'i';
        c[i] = (double)i;
    }

    Reverse(a, a + 10);//这里就是隐式实例化
    Reverse(b, b + 10);
    Reverse(c, c + 10);
    return 0;
}

模板参数 – 很多用法和函数参数是很像的
模板参数 – 传递的是类型
函数参数 – 传递的对象值

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

#include<iostream>
using namespace std;
template<class T = char>
T* func(int n)
{
       return new T[n];
}
int main()
{
       //函数模板显示实例化
       int* p = func<int>(10);//加一个<int>显式实例化
       double* p2 = func<double>(10);
       char* p3 = func(10);
       return 0;
}

2.5 模板参数的匹配原则

1.一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。
2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板。
3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

函数定义和声明分离的情况
代码示例:

//声明
template<typename T>
void Swap(T& left, T& right);
//定义
template<typename T>
void Swap(T& left, T& right)
{
       T tem = left;
       left = right;
       right = tem;
}

注意:模板不支持声明和定义放到两个文件中。声明和定义分离在两个文件就会出现链接失败
在这里插入图片描述
在这里插入图片描述


三、类模板

3.1 类模板的定义格式

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

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

template<class T>
class vector
{
public:
	//初始化列表
	vector(size_t capacity = 10);
private:
	t* _pdata;//数组
	size_t _size;
	size_t _capacity;
};
int main()
{
    // Vector类名,Vector<int>才是类型
    Vector<int> v1;
    Vector<int> v2;
}

四、非类型模板参数

概念:
模板参数分类类型形参与非类型形参。
类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

代码示例: 定义一个模板类型的静态数组

template<class T, size_t N = 10>
class array
{
public:
	T& operator[](size_t index) { return _array[index]; }
	const T& operator[](size_t index)const { return _array[index]; }
	size_t size()const { return _size; }
	bool empty()const { return 0 == _size; }
private:
	T _array[N];
	size_t _size;
};

注意:
1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
2. 非类型的模板参数必须在编译期就能确认结果。

总结和思维导图

在这里插入图片描述
总结
在这里插入图片描述

  本文总共写了四个要点,分别是泛型编程,函数模板,类模板和非类型模板参数,通过一些代码来揭示这些要点之间的关系。模板不可否认的是C++的一个重要学习内容,希望大家学完之后能有所收获!模板(下)我们主要讲模板的偏特化等知识。下期再见哦。

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

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

相关文章

如何将文字转语音?这几个软件可以将文字转语音

最近有朋友向我求助说&#xff0c;自己在学校的社团里准备了一个话剧节目&#xff0c;需要为这个节目进行旁白配音&#xff0c;但是里面的台词不仅绕口&#xff0c;还有一些是生僻字&#xff0c;念起来有点困难。要是碰上自己的课程比较多的时候&#xff0c;难以兼顾两边的工作…

使用Apache搭建网站

❤️痛苦不是失败&#xff0c;而是你本可以❤️ 实验环境 CentOS7.3&#xff08;1611&#xff09;版本、Apache2.4&#xff0c;vsftpd3.0 本次实验目的 1.编译安装httpd 2.优化路径 3.并将鲜花网站上传到web服务器为网页目录&#xff08;当然其他网站源码也可以&#xff09;…

CMU 15-213 CSAPP. Ch11. Dynamic Memory Allocation

CMU 15-213 CSAPP (Ch1~Ch3) CMU 15-213 CSAPP (Ch5~Ch7) CMU 15-213 CSAPP (Ch8) CMU 15-213 CSAPP (Ch9) CMU 15-213 CSAPP (Ch10) CMU 15-213 CSAPP (Ch11) 视频链接 课件链接 课程补充 该课程使用 64位 编译器&#xff01; Ch11. Dynamic Memory Allocation 11.1 Basic c…

【附源码】计算机毕业设计JAVA政府人才机构在线考试系统2021

【附源码】计算机毕业设计JAVA政府人才机构在线考试系统2021 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1…

《web课程设计》基于HTML+CSS+JavaScript典的中医药大学网(11个页面)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

基于Python监测键盘输入并发出声音的坤音键盘

代码和软件在公众号【走神研究所】发送【键盘】关键字获取。这是一款基于python的桌面小工具&#xff0c;能够实时显示你敲击键盘的按键&#xff0c;并且当摁下“J”、“N”、“T”、“M”时会发出坤音。具体视频演示和代码原理在这里打开程序&#xff0c;随意摁下键盘&#xf…

2022/11/27一周总结

项目 redis 安装以及启动 切换到redis根目录运行cmd&#xff0c;先启动服务端redis-server.exe 2.输入redis-cli并回车&#xff08;redis-cli是客户端程序&#xff09;如图正常提示进入&#xff0c;并显示正确端口号&#xff0c;则表示服务已经启动。 基本知识 数据类型 St…

算法提升:图的Dijkstra(迪杰斯特拉)算法

目录 概念 思路 代码 概念 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的&#xff0c;因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法&#xff0c;解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始&#xf…

【Hack The Box】linux练习-- Ophiuchi

HTB 学习笔记 【Hack The Box】linux练习-- Ophiuchi &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月27日&#x1f334; &#x1…

MySQL的执行计划explain

select_type&#xff1a;表示的查询类型 SIMPLE&#xff1a;表示查询语句不包含子查询和union;PRIMARY&#xff1a;表示此查询是最外层的查询&#xff1b;UNION: 表示此查询是UNION的第二个或后续的查询&#xff1b;DEPENDENT UNION&#xff1a;表示此查询是UNION的第二个或后续…

ARM Developer Keil MDK 5.X Crack

ARM Developer Keil MDK是面向各种STM32微控制器产品的全面软件开发解决方案&#xff0c;提供创建、编译和调试嵌入式应用程序时所需的一切资源。MDK包括真正的Arm编译器和易于使用的Keil uVision IDE/调试器&#xff0c;可与STM32CubeMX和软件包连接。MDK还提供各种专业的中间…

Faster R-CNN详解

Faster R-CNN Faster R-CNN是作者Ross Girshick继Fast R-CNN后的又一力作。使用VGG16作为网络的backbone&#xff0c;推理速度在GPU上达到5fps(包括候选区域的生成)&#xff0c;准确率也有进一步的提升。在2015年的ILSVRC以及COCO竞赛中获得多个项目的第一名。 Faster R-CNN算…

Easyrecovery2022硬盘磁盘U盘免费数据恢复软件

EasyRcovery的软件支持因各种原因损坏或误删的文件&#xff0c;文档&#xff0c;照片&#xff0c;视频&#xff0c;音频&#xff0c;电子邮件等等类型的数据它都可以恢复。同时&#xff0c;这款软件不仅仅支持u盘的数据恢复&#xff0c;移动硬盘&#xff0c;磁盘&#xff0c;sd…

【POJ No. 3067】 公路交叉数 Japan

【POJ No. 3067】 公路交叉数 Japan 北大 OJ 题目地址 【题意】 东海岸有N 个城市&#xff0c;西海岸有M 个城市&#xff08;N ≤1000&#xff0c;M ≤1000&#xff09;&#xff0c;将建成K 条高速公路。每个海岸的城市从北到南编号为1, 2, ……每条高速公路都是直线&#xf…

计算机网络---TCP流量控制和拥塞控制

&#xff08;一&#xff09; TCP 流量控制 TCP提供流量控制服务来消除发送方&#xff08;发送速率太快&#xff09;使接收方缓存区溢出的可能性&#xff0c;因此 流量控制是一个速度匹配服务&#xff08;让发送方慢一点&#xff0c;要让接收方来得及接收&#xff0c;实现匹配发…

Qt编写物联网管理平台(支持win/linux/mac/嵌入式linux/modbus等)

一、前言 这个物联网综合管理平台前后迭代了五年&#xff0c;一点一滴慢慢积累起来&#xff0c;从最开始的只有modbus串口协议解析以及简单的表格显示数据&#xff0c;慢慢的逐渐增加了tcp_rtu支持&#xff0c;用户管理模块&#xff0c;地图监控模块&#xff0c;而后为了拓展性…

消息队列 RabbitMQ入门:Linux(Docker)中安装和卸载RabbitMQ服务

文章目录前言一、Linux中安装RabbitMQ下载Erlang下载RabbitMQ进入Linux进行安装启动RabbitMQ二、RabbitMQ Web管理页面安装RabbitMQ Web管理页面访问管理页面三、使用Docker安装RabbitMQ安装Docker安装启动RabbitMQ访问管理页面四、Linux卸载RabbitMQ相关卸载RabbitMQ卸载Erlan…

第41讲:MySQL内置的QL性能分析工具

文章目录1.SQL性能分析的概念2.分析数据库中SQL的执行频率3.数据库中的慢查询日志3.1.开启慢查询日志功能3.2.模拟慢SQL查询观察日志内容4.Profile查看SQL每个阶段的耗时4.1.开启Profile操作4.2.随便执行一些查询语句4.3.查询执行SQL的耗时4.4.查询某一条SQL每个阶段的耗时4.5.…

【ASM】字节码操作 工具类与常用类 InstructionAdapter 介绍

文章目录 1.概述1.1 为什么会有 InstructionAdapter类?2. InstructionAdapter2.1 class info2.2 fields2.3 构造方法2.4 methods3.示例3.1预期目标4.总结1.概述 在上一节:【ASM】字节码操作 工具类与常用类 AnalyzerAdapter 工作原理 我们学习了AnalyzerAdapter类的工作原理…

【OpenCV 例程 300篇】246. 特征检测之ORB算法

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】246. 特征检测之ORB算法 特征检测与匹配是计算机视觉的基本任务&#xff0c;包括检测、描述和匹配三个相互关联的步骤。广泛应用于目标检测、图像检索、视频跟踪和三维重建等诸多领域。 6.9.1 ORB 算…