STL 简介(标准模板库)

前言

通过对C++的特性,类和对象的学习和C++的内存管理对C++基本上有了全面的认识,但是C++的核心在于STL

一、STL简介

什么是STL

  • C++ STL(Standard Template Library,标准模板库)是C++编程语言中一个功能强大的模板库,它提供了一系列通用的数据结构和算法。
  • STL的设计基于泛型编程,这意味着它使用模板来编写独立于任何特定数据类型的代码。
  • STL的核心组件包括容器(如向量、链表、集合等)、迭代器、算法、函数对象和适配器等。
  • 这些组件使得程序员能够以简洁、高效的方式处理数据结构和算法问题,减少了编码工作量,提高了代码的可重用性和性能

STL版本

  • HP STL:由Alexander StepanovMeng Lee在惠普实验室完成的原始版本,是所有STL实现版本的始祖。
  • PJ STL:由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用。
  • SGI STL:由Silicon Graphics Computer Systems, Inc公司开发,继承自HP版本,被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖。
  • STLport:由Boris Fomitchev开发,继承自SGI STL,旨在提供一个可移植到不同平台的STL版本

STL为什么可以成为C++标准库的一部分

  1. 泛型编程支持STL利用C++的模板机制实现了泛型编程,使得容器和算法能够处理不同类型的数据,提高了代码的重用性和灵活性。 !
  2. 高效的数据结构STL提供了多种容器类,如向量(vector)、链表(list)、双端队列(deque)、集合(set)、映射(map)等,这些容器具有高效的数据存储和访问方式,并且可以方便地进行插入、删除和查找等操作。
  3. 统一的迭代器接口STL的容器和算法都使用迭代器来访问和操作元素,迭代器提供了统一的接口,使得算法可以独立于具体的数据类型进行操作
  4. 丰富的算法库STL提供了一系列算法库,包括排序、查找、合并、堆操作、数值算法等,这些算法都被实现为函数模板,可以方便地应用于不同的容器和数据类型。
  5. 函数对象的使用STL的算法库中使用了函数对象(Functor)来封装操作,通过函数对象,STL可以将自定义的操作应用于算法中,提高了代码的可定制性和扩展性。
  6. 自动内存管理STL的容器类和算法库都采用了自动的内存管理机制,有效避免了内存泄漏和访问越界等问题。

STL六大组件

STL
仿函数
空间适配器
算法
容器
迭代器
配接器

二、模板

模板特性

  • 函数模板特化:当需要为特定类型提供不同于模板定义的函数行为时,可以使用函数模板特化。例如,对于内置类型int,可能需要一个优化过的打印函数,而对于其他类型则使用通用模板定义。
  • 类模板特化:类模板特化允许为特定类型或类型组合提供定制化的类成员函数或数据成员。这在需要为特定类型提供特定的类行为时非常有用。
  • 模板偏特化:模板偏特化是模板特化的一种形式,它允许部分参数的定制化,而保留其他参数的泛化行为。这在处理具有共同基类或接口的不同派生类型时特别有用。
  • 全特化:全特化是指为模板提供一个具体类型的实现,这样编译器在遇到该具体类型时会直接使用特化版本,而不是泛化版本。这有助于提高代码的效率和减少编译时间。
  • 参数修饰特化:参数修饰特化是通过改变模板参数的类型或数量来实现特化的技术。这可以用来解决模板参数匹配的歧义或提供额外的功能。
  • 非类型模板参数特化:非类型模板参数特化允许为特定的非类型参数值提供定制化的模板实现,这在需要根据不同的常量大小或值来调整模板行为时非常有用

泛型编程

在学习C语言的时候如果实现两个数交换 比如:整形,浮点型,字符,会写三个函数。

void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}void Swap(double& left, double& right)
{double temp = left;left = right;right = temp;
}void Swap(char& left, char& right)
{char temp = left;left = right;right = temp;
}

这样重复性的代码,是很多人讨厌的地方,正因为这个出现了泛型编程。以上的代码一个用一个函数模板替代,交给编译器实现。

template<class T>
void Swap(T& a, T& b)
{int tmp = a;a = b;b = tmp;
}
  • 在实现整形交换的时候传整形,实现浮点型减缓的时候传浮点型。

函数模板的的原理

  • 传不同的类型编译器会自动生成不同类型的函数。
//在调用这三个函数的时候编译器底层调用的函数地址是不样的
int a = 1;
int b = 2;
int c = 1.0;
int d = 2.0;
int e = 'e';
int f = 'f';
Swap(a, b);
Swap(c, d);
Swap(e, f);23: 	Swap(a, b);
00007FF760C019EE  lea         rdx,[b]  
00007FF760C019F2  lea         rcx,[a]  
00007FF760C019F6  call        Swap<int> (07FF760C012F8h)  
00007FF760C019FB  nop  24: 	Swap(c, d);
00007FF760C019FC  lea         rdx,[d]  
00007FF760C01A00  lea         rcx,[c]  
00007FF760C01A04  call        Swap<int> (07FF760C012F8h)  
00007FF760C01A09  nop  25: 	Swap(e, f);
00007FF760C01A0A  lea         rdx,[f]  
00007FF760C01A11  lea         rcx,[e]  
00007FF760C01A18  call        Swap<int> (07FF760C012F8h)  
00007FF760C01A1D  nop  

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

类模板

类模板是一种强大的编程技术,它允许开发者定义泛型类,这些类可以在创建时指定不同的数据类型。

类模板的定义

  1. 关键字template:用于声明模板的开始。
  2. 模板参数列表:位于尖括号< >内,定义了模板的类型参数或非类型参数。类型参数通常使用typenameclass关键字声明。
  3. 类模板名:紧随模板参数列表之后,是模板的名称。
  4. 类模板体:包含类模板的成员声明,可以是类的定义、函数定义或类型别名等。
template <typename T>
class MyClass {
public:T member;MyClass(T initialValue) : member(initialValue) {}// 其他成员函数和类型定义
};

模板的实例化

  • 函数模板实例化是指编译器根据函数模板和具体类型的实参生成特定类型的函数定义的过程。

隐式实例化

  • 隐式实例化是编译器在遇到函数模板调用时自动进行的实例化过程。编译器根据函数调用的实参类型来推导模板参数的实际类型,并生成相应的模板函数实例。

例如,如果有一个模板函数 template <typename T> void f(T a, T b),当调用 f(1, 2) 时,编译器会自动实例化一个 f<int>(int, int) 的函数版本。

//写出一个模板
template<class T>
void Swap(T& a, T& b)
{int tmp = a;a = b;b = tmp;
}
//在调用f(1,1),会生成 int swap(int& a,int& b)
int swap(int& a,int b)
{int tmp = a;a = b;b = tmp;
}

显示实例化

  • 显式实例化是指程序员在代码中明确指定模板实例化的具体类型,以便提前生成相应的模板函数实例。
//写出一个模板
template<class T>
void Swap(T& a, T& b)
{int tmp = a;a = b;b = tmp;
}
//在调用f<int>(1.0,1.0),会生成 int swap(float& a,float& b)
int swap(float& a,float& b)
{int tmp = a;a = b;b = tmp;
}

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

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

相关文章

【Linux】CentOS更换国内阿里云yum源(超详细)

目录 1. 前言2. 打开终端3. 确保虚拟机已经联网4. 备份现有yum配置文件5. 下载阿里云yum源6. 清理缓存7. 重新生成缓存8. 测试安装gcc 1. 前言 有些同学在安装完CentOS操作系统后&#xff0c;在系统内安装比如&#xff1a;gcc等软件的时候出现这种情况&#xff1a;&#xff08…

前端 socket.io 跨域

在使用Socket.io进行前端跨域通信时&#xff0c;可以通过设置Socket.io的cors选项来允许跨域请求。 以下是一个简单的例子&#xff0c;展示了如何在Node.js的服务器代码中配置Socket.io以允许跨域连接&#xff1a; const express require(express); const http require(http…

【C++进阶学习】第九弹——哈希的原理与实现——开放寻址法的讲解

前言&#xff1a; 在前面&#xff0c;我们已经学习了很多存储机构&#xff0c;包括线性存储、树性存储等&#xff0c;并学习了多种拓展结构&#xff0c;效率也越来越高&#xff0c;但是是否有一种存储结构可以在大部分问题中都一次找到目标值呢&#xff1f;哈希可能能实现 目录…

Vite项目中根据不同打包命令配置不同的后端接口地址,proxy解决跨域

在vite.config.ts同级目录添加两个文件 .env.development #开发环境 VITE_APP_ENV developmentVITE_APP_BASE_API .env.production #生产配置 VITE_APP_ENV productionVITE_APP_BASE_API https://www.bdjw.work代码中使用路径 const request axios.create({baseURL: i…

Maven已经导入Junit包,但是还是无法使用注解

Maven已经导入Junit包&#xff0c;但是还是无法使用注解 背景&#xff1a; 导入了Junit的依赖 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></d…

【Python的GDAL/OGR库】

GDAL/OGR库是一个开源的地理数据处理库&#xff0c;用于读取、写入和转换各种地理数据格式。以下是对GDAL/OGR库的详细解释&#xff1a; GDAL&#xff08;Geospatial Data Abstraction Library&#xff09; 定义&#xff1a;GDAL是一个在X/MIT许可协议下的开源栅格空间数据转…

【初阶数据结构题目】2.移除元素

文章目录 顺序表算法题代码&#xff1a; 顺序表算法题 点击链接做题 移除元素 思路&#xff1a;定义两个变量指向数组第一个位置&#xff0c;判断nums[src]是否等于val 相等&#xff0c;src不相等&#xff0c;nums[dst] nums[src],src,dst 代码&#xff1a; int removeElem…

如何使用CANoe自带的TCP/IP Stack验证TCP的零窗口探测机制

如果想利用CANoe自带的TCP/IP协议栈验证TCP的零窗口探测机制,就必须添加一个网络节点并配置独立的CANoe TCP/IP协议栈,作为验证对象。而与它进行TCP通信的对端也是一个网络节点,但不要配置TCP/IP协议栈,而是使用CAPL代码在底层组装TCP报文模拟TCP通信过程。这样可以尽量减少…

postgrsql——事务概述

事务概述 事务的特性 原子性&#xff08;Atomicity&#xff09;&#xff1a; 事务被视为一个整体&#xff0c;其中的操作要么全部执行成功&#xff0c;要么全部不执行&#xff0c;即不存在部分执行的情况。这确保了事务的完整性和一致性。一致性&#xff08;Consistency&…

C——简介

一、C语言的诞生背景 C语言的诞生并非偶然&#xff0c;它是为了解决当时编程环境中存在的问题而设计的。在C语言出现之前&#xff0c;编程主要依赖于汇编语言&#xff0c;这种语言虽然执行效率高&#xff0c;但编写和维护都极其复杂且容易出错。与此同时&#xff0c;高级语言如…

轻松入门Linux—CentOS,直接拿捏 —/— <1>

一、什么是Linux Linux是一个开源的操作系统&#xff0c;目前是市面上占有率极高的服务器操作系统&#xff0c;目前其分支有很多。是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统 Linux能运行主要的UNIX工具软件、应用程序和网络协议 Linux支持 32…

基于Drone实现CI/CD【0到1架构系列】

CI/CD是持续性集成和持续性部署&#xff0c;简单来讲就是自动化构建和自动化部署。目前有很多集成方案&#xff0c;也有很多组装方案&#xff0c;只要能实现自动化构建出制品&#xff0c;再自动部署到生产环境就行。 目前很多源代码都集成了CI/CD功能&#xff0c;drone也是目前…

还在用JVM跑你的Java代码吗?太慢了,试试Oracle的GraalVM吧

前言 对于Java开发者们来说&#xff0c;几乎每天都在和JVM打交道&#xff0c;然而JVM即将过时了。那些对新技术保持敏锐洞察力的开发者&#xff0c;可能已经在生产环境中部署GraalVM生成的二进制程序了&#xff0c;小伙伴们&#xff0c;你们已经用起来了吗&#xff1f; Graal…

【初阶数据结构题目】3.删除有序数组中的重复项

文章目录 顺序表算法题代码&#xff1a; 顺序表算法题 点击链接做题 删除有序数组中的重复项 思路&#xff1a;定义两个指针变量。dst指向数组第一个位置&#xff0c;src指向数组第二个位置。判断nums[dst]是否等于nums[src] 相等&#xff0c;src不相等&#xff0c;dst,nums[…

Windows 11 桌面模拟

Windows 11 桌面模拟 文章目录 Windows 11 桌面模拟代码结构HTML结构CSS样式JavaScript功能 源码效果图 代码结构 HTML结构 <html>: HTML文档的根元素。<head>: 包含文档的元数据&#xff0c;如标题和样式。<base>: 指定相对URL的基准。<title>: 指定…

力扣刷题160 相交链表

题目 力扣题目地址&#xff0c;点此可直接跳转 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 来源&#xff1a;力扣&…

60、redis安装和部署

一、关系型数据库与非关系型数据库 1.1、关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;创建在关系模型&#xff08;二维表格模型&#xff09;基础上一般面向于记录。SQL语句&#xff08;标准数据查询语言&#xff09;就是一种基于关系型数据库的语言&#xff0…

Laravel API资源收集器:打造高效数据响应的秘诀

Laravel API资源收集器&#xff1a;打造高效数据响应的秘诀 引言 在构建API时&#xff0c;数据的响应格式对于客户端的易用性和API的可维护性至关重要。Laravel框架提供了一种优雅的方式来处理API响应&#xff0c;即API资源&#xff08;API Resources&#xff09;和资源收集器…

SQL进阶技巧:如何分析共同好友问题?

目录 0 需求 1 数据准备 2 数据分析 3 小结 0 需求 给定每个用户的好友列表,好友关系是互相对称的,返回任意两个用户的共同好友列表 1 数据准备 with common_friend as( select A as id , B,C,D as friends union all select B as id , A,C,E as friends union all s…

pycharm 新建Python项目 使用anaconda环境

1.pycharm 新建完Python项目 2.文件-设置-具体项目-Python解释器-添加解释器-Conda执行文件选择你自己anaconda安装目录下Scripts\conda.exe -加载环境-选择现有的Conda环境或者新建一个环境