当前位置: 首页 > news >正文

模板、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;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • VisualRules-Web案例展示(一)
  • mysql、oracle、db2数据库连接参数
  • SpringSecurity通用权限管理系统
  • 关于合芯新通RTK配置的方法记录7.23
  • k8s部署rabbitmq集群
  • Json结构解析比较
  • 69、ncnn学习onnx2ncnn不支持带三维算子相乘gemm/repeat转换方法学习
  • CH04_依赖项属性
  • day02 mybatis
  • 微信小程序数组绑定使用案例(二)
  • 《流程引擎原理与实践》开源电子书
  • 【大数据专题】数据仓库
  • 从零开始手写STL库:List
  • Huawei、Cisco 路由中 RIP 协议 summary 的用法
  • 基于深度学习的商品推荐
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • Android Volley源码解析
  • cookie和session
  • Effective Java 笔记(一)
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • java8-模拟hadoop
  • MaxCompute访问TableStore(OTS) 数据
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • session共享问题解决方案
  • Spring核心 Bean的高级装配
  • SQLServer之创建数据库快照
  • 高度不固定时垂直居中
  • 技术胖1-4季视频复习— (看视频笔记)
  • 力扣(LeetCode)21
  • 如何选择开源的机器学习框架?
  • 时间复杂度与空间复杂度分析
  • 数组大概知多少
  • 网络应用优化——时延与带宽
  • 怎么把视频里的音乐提取出来
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # Apache SeaTunnel 究竟是什么?
  • #APPINVENTOR学习记录
  • #vue3 实现前端下载excel文件模板功能
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (待修改)PyG安装步骤
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (四)Controller接口控制器详解(三)
  • (四)事件系统
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (一)基于IDEA的JAVA基础10
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .NET CORE 第一节 创建基本的 asp.net core
  • .NET CORE Aws S3 使用
  • .net core Redis 使用有序集合实现延迟队列
  • .net dataexcel 脚本公式 函数源码