【C++】模版初阶以及STL的简介

在这里插入图片描述
个人主页~


模版及STL

  • 一、模版初阶
    • 1、泛型编程
    • 2、函数模版
      • (1)概念
      • (2)函数模版格式
      • (3)函数模版的原理
      • (4)函数模版的实例化
        • ①显式实例化
        • ②隐式实例化
      • (5)模版参数的匹配原则
    • 3、类模版
      • (1)类模板的定义格式
      • (2)类模板的实例化以及类函数的使用
  • 二、STL简介

一、模版初阶

1、泛型编程

我们在先前的博文中提到过函数重载交换函数swap,但是使用函数重载有几个不好的地方:
1、重载的函数仅仅是类型不同,代码复用率比较低,所有的重载函数中只有数据类型不同,其他的都基本相同, 只要有新类型出现就需要用户自己增加对应的函数
2、代码可维护性低,其中某一函数出错可能会导致所有重载都出错

解决这个问题的方法就是有一个模具,只要相同的就直接套用,不同的替换就可以了

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

2、函数模版

(1)概念

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

(2)函数模版格式

template<typename T1,typename T2,...>
type name ()
{}

template就是一个函数模版关键字后跟<>,参数放里边
typename是一个类类型参数,也可以写成class,但不能写成struct,它代表name函数可以操作的数据类型。当调用name函数时,编译器会根据传递给函数的实参类型来推断T的具体类型
type name(){}就是一个函数

具体看这个例子:

template<typename T>
void Swap( T& left, T& right)
{T temp = left;left = right;right = temp;
}

(3)函数模版的原理

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

在编译器的编译阶段,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用,将T确定为某一具体类型,然后产生一份专门处理该类型的代码

(4)函数模版的实例化

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

①显式实例化
template<typename T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{int a = 10;double b = 20.0;// 显式实例化Add<int>(a, b);return 0;
}

格式:函数名+<数据类型>(参数)

②隐式实例化
template<typename T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, a2);//意味着T实例化为intAdd(d1, d2);//意味着T实例化为doublereturn 0;
}

在这里插入图片描述
这是当两个参数类型相同的时候,如果两参数类型不同该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型,通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T,编译器无法确定此处到底该将T确定为int 或者 double类型而报错,所以我们要进行手动强制类型转换
在这里插入图片描述
在这里插入图片描述

注意:在模板中,编译器一般不会进行类型转换操作

(5)模版参数的匹配原则

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

int Add(int left, int right)
{return left + right;
}template<typename T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{cout << Add(1, 2) << endl;//直接与非模版函数相匹配,编译器不需要进行特化cout << Add<int>(1, 2) << endl;//调用编译器特化的Add版本return 0;
}

在这里插入图片描述

调试结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
②对于非模版函数和同名函数模版,如果其他条件都相同,在调动时会优先调用非模版函数而不会从该模版产生出一个实例,但如果模版可以产生一个具有更好的匹配的函数,那么将选择模版

int main()
{Add(1, 2);//非模版更匹配,会直接选择非模版函数,不必再特化Add(1, 2.0);//模版生成的函数比非模版函数更加匹配,这样就会选择模版return 0;
}

③普通函数可以进行自动类型转换,模版函数不允许自动类型转换

3、类模版

(1)类模板的定义格式

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

name是类模板名

接下来我们写一个动态顺序表的模版

template<class T>
class Vector//Vector是类模版名,不是类
{
public:Vector(size_t capacity = 10): _pData(new T[capacity]), _size(0), _capacity(capacity){}
//模版外定义函数~Vector();void PushBack(const T& data);
//模版内定义函数void PopBack(){_size--;}size_t Size(){return _size;}private:T* _pData;size_t _size;size_t _capacity;
};
// 类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{if (_pData)delete[] _pData;_size = _capacity = 0;
}
//每次函数定义都要加模版参数列表
template <class T>
void Vector<T>::PushBack(const T& data)
{if (_size == _capacity){size_t newcapacity = _capacity * 2;T* ptr = new T[newcapacity];for (int i = 0; i < _size; i++){ptr[i] = _pData[i];}delete[] _pData;//用delete[]回收new[]申请的空间_pData = ptr;_capacity = newcapacity;}_pData[_size] = data;_size++;
}

(2)类模板的实例化以及类函数的使用

类模板实例化需要在类模板名字后加<>,然后将实例化的类型放在里边,类模板不是类,实例化后才为类

int main()
{Vector<int> s1;s1.PushBack(1);s1.PushBack(2);s1.PushBack(3);s1.PushBack(4);s1.PopBack();cout << s1.Size() << endl;Vector<double> s2;return 0;
}

在这里插入图片描述
调试结果:
在这里插入图片描述
在这里插入图片描述

二、STL简介

STL是标准库的组成部分,是一个可复用的组件库和包罗数据结构与算法的软件框架

STL有四个版本,分别是惠普版本(也叫原始版本)、P.J.版本(VC)、RW版本、SGI版本(Linux)

STL由容器、算法、仿函数、空间配置器、迭代器、配接器六大组件构成

STL的产生是C++的一次巨变,它使得很多底层的数据结构及算法不用再让程序员来实现,大大提高了学习和工作的效率和开发产品的进度

当然,STL也有更新慢、不支持线程安全、内部复杂、代码膨胀等问题


今日分享到此结束~
在这里插入图片描述

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

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

相关文章

精益六西格玛项目赋能,石油机械龙头企业质量效率双提升!

​国内某石油机械制造龙头&#xff0c;迎接挑战&#xff0c;迈向卓越&#xff0c;携手张驰咨询&#xff0c;启动精益六西格玛项目&#xff0c;开启管理革新新篇章。 在国家政策调整和市场竞争日益激烈的背景下&#xff0c;作为国内石油机械产品制造领域的龙头企业&#xff0c;…

算法 —— LRU算法

算法 —— LRU算法 LRULRU算法的工作原理&#xff1a;实现方法&#xff1a;性能考虑&#xff1a; 模拟过程splice函数对于std::list和std::forward_list基本语法&#xff1a;功能描述&#xff1a; 示例&#xff1a;注意事项&#xff1a; 如果大家已经学习过了Cache的替换算法和…

Linux——Shell脚本和Nginx反向代理服务器

1. Linux中的shell脚本【了解】 1.1 什么是shell Shell是一个用C语言编写的程序&#xff0c;它是用户使用Linux的桥梁 Shell 既是一种命令语言&#xff0c;有是一种程序设计语言 Shell是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问…

开放式耳机2024哪家品牌比较好?2024年爆火开放式耳机推荐

很多小伙伴在后台私信我&#xff0c;滴滴我说&#xff0c;最近开放式耳机这么火&#xff0c;他也想要入手一台问问我&#xff0c;有哪些开放式耳机值得现在入手的&#xff0c;作为一个尽职尽业的数码博主&#xff0c;我本来是一个个回复的&#xff0c;但是私信没想到这么多&…

[C++初阶]list的模拟实现

一、对于list的源码的部分分析 1.分析构造函数 首先&#xff0c;我们一开始最先看到的就是这个结点的结构体&#xff0c;在这里我们可以注意到这是一个双向链表。有一个前驱指针&#xff0c;一个后继指针。然后在有一个存储数据的空间 其次它的迭代器是一个自定义类型&#x…

pyinstall 打包基于PyQt5和PaddleOCR的项目为.exe

简介&#xff1a; 最近做了一个小项目&#xff0c;是基于PyQt5和PaddleOCR的。需要将其打包为.exe&#xff0c;然后打包过程中遇到了很多问题&#xff0c;也看了很多教程&#xff0c;方法千奇百怪的&#xff0c;最后也是一步一步给试出来了。记录一下&#xff0c;防止以后忘记…

CSS基础学习之元素定位(6)

目录 1、定位类型 2、取值 2.1、static 2.2、relative 2.3、absolute 2.4、fixed 2.5、stickty 3、示例 3.1、相对定位(relative) 3.2、绝对定位&#xff08;absolute&#xff09; 3.3、固定定位&#xff08;fixed&#xff09; 3.4、粘性定位&#xff08;sticky&…

智慧互联新时代,Vatee万腾平台引领行业变革

在科技日新月异的今天&#xff0c;我们正步入一个前所未有的智慧互联新时代。这个时代&#xff0c;信息如潮水般涌来&#xff0c;数据成为新的石油&#xff0c;驱动着各行各业发生深刻变革。在这场变革的浪潮中&#xff0c;Vatee万腾平台以其卓越的智慧互联技术和前瞻性的战略布…

vue3前端开发-执行npm run dev提示报错怎么解决

vue3前端开发-执行npm run dev提示报错怎么解决&#xff01;今天在本地安装初始化了一个vue3的案例demo。但是当我执行npm run dev想启动它时报错了说&#xff0c;找不到dev。让我检查package.json文件是否包含dev。如下图所示&#xff1a; 实际上&#xff0c;不必惊慌&#xf…

2024全球和国内最常用的弱密码,有没有你的?

密码管理器NordPass分析了来自公开来源的超过4.3TB 的密码数据&#xff0c;找出了当前为止&#xff08;2024年&#xff09;最常用&#xff08;最脆弱&#xff09;的密码。 这些密码主要有下面这些特征&#xff1a; 简单且常用&#xff0c;万年弱密码&#xff0c;比如123456、a…

获利能力段部分特征值不更新,需要手动点派生才更新的问题

一、问题描述&#xff1a;销售订单修改某些特征值字段&#xff0c;保存后&#xff0c;获利能力段对应的字段值没更新。 比如&#xff1a;把销售订单销售组从Z09修改为Z04&#xff0c;保存后&#xff0c;获利能力段重的销售组还是旧值Z09。 1、修改销售组为Z04,然后保存 2、销售…

mac拆分pdf mac如何拆分pdf成多个文件

在数字化办公日益普及的今天&#xff0c;pdf文件因其良好的兼容性和便捷性&#xff0c;已经成为工作和学习中的重要文件格式。然而&#xff0c;有时候我们可能会遇到需要将一个大的pdf文件拆分成多个小文件的情况&#xff0c;以便于管一理和分享。本文将为您详细介绍两种简单易…

【BUG】已解决:java.lang.reflect.InvocationTargetException

已解决&#xff1a;java.lang.reflect.InvocationTargetException 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发…

[word] word如何编写公式? #微信#知识分享

word如何编写公式&#xff1f; word如何编写公式&#xff1f;Word中数学公式是经常会使用到的&#xff0c;若是要在文档中录入一些复杂的公式&#xff0c;要怎么做呢&#xff1f;接下来小编就来给大家讲一讲具体操作&#xff0c;一起看过来吧&#xff01; 方法一&#xff1a;…

【机器学习】--过采样原理及代码详解

过采样&#xff08;Oversampling&#xff09;是一个在多个领域都有应用的技术&#xff0c;其具体含义和应用方法会根据领域的不同而有所差异。以下是对过采样技术的详细解析&#xff0c;主要从机器学习和信号处理两个领域进行阐述。 一、机器学习中的过采样 在机器学习中&…

完美的用户体验:如何设计一个直观和有效的网站导航?

APP的顶部导航栏对我们来说很熟悉。导航栏是UI设计中不可或缺的一部分&#xff0c;几乎每个页面都使用导航栏。虽然导航栏看起来很简单&#xff0c;不需要太多精力&#xff0c;但是设计一个与产品需求和客户目标高度匹配的导航栏并不是那么容易的。导航栏的设计标准有很多细节需…

JavaWeb服务器-Tomcat(Tomcat概述、Tomcat的下载、安装与卸载、启动与关闭、常见的问题)

Tomcat概述 Tomcat服务器软件是一个免费的开源的web应用服务器。是Apache软件基金会的一个核心项目。由Apache&#xff0c;Sun和其他一些公司及个人共同开发而成。 由于Tomcat只支持Servlet/JSP少量JavaEE规范&#xff0c;所以是一个开源免费的轻量级Web服务器。 JavaEE规范&…

JavaScript 中怎么看数据返回值

文章目录 前言console.log()1. 输出简单的文本2. 输出变量3. 输出表达式的结果4. 输出对象和数组5. 输出多个参数6. 使用模板字符串7. 输出错误信息 alert()基本用法使用场景注意事项 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 我只知道后端程序跑…

React学习笔记02-----React基本使用

一、React简介 想实现页面的局部刷新&#xff0c;而不是整个网页的刷新。AJAXDOM可以实现局部刷新 1.特点 &#xff08;1&#xff09;虚拟DOM 开发者通过React来操作原生DOM&#xff0c;从而构建页面。 React通过虚拟DOM来实现&#xff0c;可以解决DOM的兼容性问题&#x…

跳动的爱 - 动态全屏爱心【前端版本】

要使用HTML、CSS和JavaScript绘制一个全屏且较大的爱心&#xff0c;并且让它有动态效果&#xff0c;可以通过以下步骤实现&#xff1a; HTML: 定义基本的页面结构。 CSS: 定义爱心的样式和动画效果。 JavaScript: 动态调整爱心的位置和大小&#xff0c;使其在页面上移动。 下面…