【C++】——模板初阶 | STL简介

在这里插入图片描述

前言:
模板初阶 | STL简介


文章目录

  • 一、模板初阶
    • 1.1 函数模板
    • 1.2 类模板
  • 二、STL简介 (了解)

一、模板初阶

泛式编程(Generic Programming)指的是一种编程范式,其核心思想是编写可以在不同数据类型上通用的代码,从而提高代码的复用性、可维护性和可扩展性。

泛式编程的实现方式包括模板(Template)和泛型(Generics)。在C++中,使用模板可以实现泛型编程,而在Java、C#等语言中,则使用泛型来实现类似的功能。


1.1 函数模板

函数模板的格式如下:

template <typename T1,typename T2,......,typename Tn>
返回类型 函数名(参数列表) {// 函数体
}
  • template <typename T1,typename T2,......,typename Tn>:以关键字 template 开始,后跟尖括号 < >,里面是一个或多个模板参数的列表。例如typename T1 定义了一个类型模板参数 T1,可以替换为其他任意合法的标识符。

  • 返回类型:函数的返回类型,可以是任意类型。

  • 函数名:函数的名称,可以是任意合法的标识符。

  • 参数列表:函数的参数列表,可以包含零个或多个参数,每个参数可以是任意合法的标识符,也可以是模板参数。

  • 函数体:函数的具体实现,包括函数的操作和逻辑。

一个具体的函数模板示例:

// 函数模板的定义
template <typename T>
T maximum(T x, T y) {return (x > y) ? x : y;
}// 调用模板函数
int result1 = maximum(10, 20);
double result2 = maximum(3.14, 2.71);

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


函数模板实例化
函数模板的实例化是指根据具体的类型,生成模板函数的过程。当编译器在代码中遇到对函数模板的调用时,它会根据传递的参数类型推导出模板参数的具体类型,并生成相应的函数实例。

// 定义函数模板
template <typename T>
T maximum(T x, T y) {return (x > y) ? x : y;
}int main() {int result1 = maximum(10, 20); // 实例化为 maximum<int>(10, 20),T 被推导为 intdouble result2 = maximum(3.14, 2.71); // 实例化为 maximum<double>(3.14, 2.71),T 被推导为 double//或者我们可以手动进行实例化// 手动实例化模板函数为 int 类型int result3 = maximum<int>(10, 20);// 手动实例化模板函数为 double 类型double result4 = maximum<double>(3.14, 2.71);return 0;
}

函数模板的实例化是在编译时进行的,每次调用函数模板时,都会根据传递的参数类型生成相应的函数实例。这样,同一个函数模板可以用于多种不同类型的参数,实现了通用的函数。


模板参数的匹配原则
一个非模板函数和一个同名的函数模板可以同时存在,编译器会根据一定的匹配规则来确定使用哪一个函数。

  1. 如果函数调用的参数列表与非模板函数的参数列表精确匹配,那么将调用非模板函数。
  2. 如果函数调用的参数列表可以匹配到函数模板的模板参数类型,并且生成一个能够匹配的实例化函数,那么将调用函数模板的实例化版本。

例如:

// 非模板函数
void foo(int x) {cout << "Non-template function: " << x << endl;
}// 函数模板
template <typename T>
void foo(T x) {cout << "Function template: " << x << endl;
}int main() {foo(42); // 调用非模板函数foo("hello"); // 调用函数模板return 0;
}

在这个例子中,调用 foo(42) 时会匹配到非模板函数 foo(int),因为参数类型 int 精确匹配。而调用 foo("hello") 时会匹配到函数模板 foo(T),并实例化为 foo(const char*),因为函数模板的模板参数可以匹配到参数类型 const char*


1.2 类模板

除函数模板外,类模板是C++中另一个重要的模板形式,允许定义通用的类,其中的某些成员类型或成员函数可以由用户指定。类模板以 template <typename T>template <class T> 开始,后跟着类的定义,其中 T 是一个占位符类型,表示任意类型。

例如我们创建一个类,类的对象的类型可能是int或者char等等:

template <class T, int N>
class Stack {
private:T elements[N];int top; // 栈顶索引
public:Stack() : top(-1) {} // 初始化栈顶索引为-1void push(const T& element) {if (top == N - 1) {// 栈满,抛异常throw std::overflow_error("Stack<>::push(): stack overflow");}elements[++top] = element; // 将元素入栈}
};

这个示例中,Stack 是一个类模板,有两个模板参数:T 表示元素的类型,N 表示栈的最大容量。

//类模板实例化
Stack<int, 10> intStack; // 创建一个最大容量为 10 的整型栈
Stack<double, 5> doubleStack; // 创建一个最大容量为 5 的双精度浮点型栈

当类模板中的函数定义放在类外部时,如果函数使用了类模板的模板参数,那么函数定义必须在其前面加上模板参数列表,并且在函数名之后使用类模板的模板参数,以表明该函数是属于类模板的。

例如:

template <typename T>
class Stack {
public:void push(const T& element); // 函数声明
};// 函数定义放在类外部
template <typename T>
void Stack<T>::push(const T& element) {// 函数定义
}

二、STL简介 (了解)

STL 是 C++ 标准模板库(Standard Template Library)的缩写。它是 C++ 标准库的一部分,提供了一系列的通用模板类和函数,用于实现各种常见的数据结构和算法,例如向量(vector)、链表(list)、栈(stack)、队列(queue)、集合(set)、映射(map)等,以及对这些数据结构进行操作的算法,如排序、查找、遍历等。

STL 的设计思想是基于泛型编程(Generic Programming),它使用模板技术实现通用性和灵活性,使得用户能够在不同的数据类型上使用相同的算法和数据结构。STL 提供了大量的模板类和函数,使得程序员可以在开发过程中更加高效地处理各种数据结构和算法问题。

STL(Standard Template Library)的六大组件:
在这里插入图片描述

  1. 容器(Containers)
    容器是用于存储和管理数据的数据结构,包括向量(vector)、链表(list)、双端队列(deque)、队列(queue)、栈(stack)、集合(set)、映射(map)等。每种容器都有不同的特点和适用场景,可以根据具体的需求选择合适的容器。

  2. 算法(Algorithms)
    算法是用于对容器中的元素进行操作和处理的函数,包括排序、查找、遍历、拷贝、删除等一系列操作。STL提供了大量的算法,能够满足各种不同的需求,提高代码的复用性和可读性。

  3. 迭代器(Iterators)
    迭代器是一种用于遍历容器中元素的对象,它提供了统一的访问接口,使得算法能够与容器解耦合。STL提供了多种类型的迭代器,包括输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器,每种迭代器都有不同的功能和特点。

  4. 仿函数(Functors)
    仿函数是一种可调用对象,它可以像函数一样被调用,并且可以作为算法的参数使用。仿函数可以是普通函数指针、函数对象(重载了函数调用运算符 operator() 的类对象)、Lambda 表达式等。STL提供了一些内置的仿函数,同时也支持用户自定义的仿函数。

  5. 适配器(Adapters)
    适配器是一种用于在不同容器之间进行转换和包装的机制,它可以将一个容器转换为另一个容器,或者在一个容器的基础上提供新的功能。STL提供了一些常用的适配器,如栈适配器(stack)、队列适配器(queue)、优先队列适配器(priority_queue)等。

  6. 配置器(Allocators)
    配置器是一种用于内存管理的机制,它控制着容器在内存中的分配和释放。STL中的容器和算法都使用了配置器来进行内存管理,但配置器的具体实现通常是由编译器提供的默认配置器。STL也允许用户自定义配置器,以满足特定的需求。

这些六大组件构成了STL的核心部分,它们共同组成了一个功能强大、高效易用的库,为C++程序员提供了丰富的数据结构和算法,极大地提高了程序开发的效率和质量。


在这里插入图片描述
如果你喜欢这篇文章,点赞👍+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。

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

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

相关文章

智能科技助力服装业:商品计划管理系统的革命性变革

随着智能科技的飞速发展&#xff0c;服装行业正在经历前所未有的变革。在这股浪潮中&#xff0c;商品计划管理系统的智能化转型成为了行业的核心驱动力。这种变革不仅极大地提高了服装企业的运营效率和市场竞争力&#xff0c;更为整个行业的可持续发展注入了新的活力。 智能商…

你听说过柔性数组吗?

目录 1. 柔性数组的概念 2. 柔性数组的特点 3. 柔性数组的使用 4. 柔性数组的优势 5.完结散花 悟已往之不谏&#xff0c;知来者犹可追 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#…

怎么理解ping?这是我听过最好的回答

晚上好&#xff0c;我是老杨。 Ping这几个字母&#xff0c;已经深入网工人的骨髓了吧&#xff1f; 把Ping用到工作里&#xff0c;肯定不少人在用&#xff0c;但对Ping的了解和理解是不是足够深&#xff0c;取决了你能在工作里用到什么程度&#xff0c;能让它帮你到什么地步。…

美格智能联合罗德与施瓦茨完成5G RedCap模组SRM813Q验证,推动5G轻量化全面商用

全球5G发展进入下半场&#xff0c;5G RedCap以其低成本、低功耗的特性成为行业焦点。近日&#xff0c;中国移动携手合作伙伴率先完成全球最大规模、最全场景、最全产业的RedCap现网规模试验&#xff0c;推动首批芯片、终端具备商用条件&#xff0c;RedCap端到端产业已全面达到商…

10.CSS3的calc函数

CSS3 的 calc 函数 经典真题 CSS 的计算属性知道吗&#xff1f; CSS3 中的 calc 函数 calc 是英文单词 calculate&#xff08;计算&#xff09;的缩写&#xff0c;是 CSS3 的一个新增的功能。 MDN 的解释为可以用在任何长度、数值、时间、角度、频率等处&#xff0c;语法如…

Spring6学习技术|Junit

学习材料 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09; Junit 背景 背景就是每次Test都要重复创建容器&#xff0c;获取对象。就是ApplicationContext和getBean两个语句。通过Spring整合Junit&#xff0c;可以…

sentinel的资源数据指标是如何采集

资源数据采集 之前的NodeSelectorSlot和ClusterBuilderSlot已经完成了对资源调用树的构建, 现在则是要对资源进行收集, 核心点就是这些资源数据是如何统计 LogSlot 作用: 记录异常请求日志, 用于故障排查 public class LogSlot extends AbstractLinkedProcessorSlot<Def…

统计图雷达图绘制方法

统计图雷达图绘制方法 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制&#xff0c;饼图环形图绘制较难。 还有一种雷达图的绘制也较难&#xff0c;今提供雷达图的绘制方法供参考。 本方法采用C语言的最基本功能&#xff1a; &am…

跟着野火学FreeRTOS:第二段(事件组)

在小节里面介绍了二进制信号量&#xff0c;计数信号量&#xff0c;互斥量和递归互斥量等功能&#xff0c;其中二进制信号量和计数信号量&#xff08;也包括队列&#xff09;常用于任务和任务之间以及任务和中断之间的同步&#xff0c;她们具有以下属性&#xff1a; 当等待的事…

Day15-Linux系统特殊权限知识精讲

Day15-Linux系统特殊权限知识精讲 为什么创建文件默认权限为644&#xff0c;目录为755&#xff1f;&#xff1f;&#xff1f; umask 权限掩码。控制系统的文件和目录的默认权限。 [rootoldboy oldboy]# umask 0022针对文件来说&#xff1a;默认权限计算方法 6 6 6 0 2 2 - …

为什么0.1+0.2不等于0.3

一、JS内部的计算是以二进制形式进行的 js里整数和小数转为二进制形式的方法是不一样的&#xff1a; 二、Number类型使用IEEE754标准64位存储 双精度浮点数&#xff08;double类型&#xff09;为每个数分配64位空间&#xff0c;并以科学计数法的方式存储&#xff1a; 那么对于…

C++入门学习(三十三)函数的定义,两数之和函数作为例子

为什么使用函数&#xff1a;将一些重复的代码封装&#xff0c;方便以后的使用&#xff0c;直接调用即可。 先给一个例子&#xff1a; // 函数返回整数类型 int addNumbers(int a, int b) { // 函数体 int sum a b; return sum; // 返回计算得到的和 } 返回值类型&…

基于卷积神经网络的图像去噪

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 基于卷积神经网络的图像去噪 完整代码:基于卷积神经网络的图像去噪.rar资源-CSDN文库 https://download.csdn.net/download/abc9918351…

(全注解开发)学习Spring-MVC的第三天

全注解开发 第一部分 : 1.1 消除spring-mvc.xml 这些是原来spring-mvc.xml配置文件的内容 <!--1、组件扫描, 使Controller可以被扫描到--><context:component-scan base-package"com.itheima.controller"/><!--2、非自定义的Bean, 文件上传解析器--&…

mysql-多表查询-外连接

一、外连接查询语法 &#xff08;1&#xff09;左外连接 select 所要查询的内容 from 左表 left outer join 右表 on 条件; &#xff08;2&#xff09;右外连接 select 所要查询的内容 from 左表 right outer join 右表 on 条件; 二、示例 用以下两张表示例 左外连接 右外…

Pyglet综合应用|推箱子游戏之关卡图片载入内存

目录 读取图片 分割图片 综合应用 本篇为之前写的博客《怎样使用Pyglet库给推箱子游戏画关卡地图》的续篇&#xff0c;内容上有相关性&#xff0c;需要阅读的请见链接&#xff1a; https://hannyang.blog.csdn.net/article/details/136209138 「推箱子」是一款风靡全球的益…

system V 共享内存

1.共享内存的原理 要理解共享内存的原理&#xff0c;首先我们得记起进程间通信的前提&#xff1a;必须让不同的进程看到同一份资源&#xff08;必须由OS提供&#xff09; 我们都知道进程都会有自己的进程地址空间&#xff0c;然后都会通过页表与物理内存进行映射&#xff0c;…

图纸透明加密:保护机械图纸安全的新方法

随着信息技术的不断发展&#xff0c;机械制造行业对于图纸安全的需求越来越高。机械图纸是企业的核心竞争力之一&#xff0c;泄露可能导致严重的商业损失和技术风险。为了解决这一问题&#xff0c;图纸透明加密成为了一种新的保护机械图纸安全的方法。本文将介绍图纸透明加密的…

面试字节跳动,我被怼的好狠,怎一个惨字了得

人们都说&#xff0c;这个世界上有两种人注定单身&#xff0c;一种是太优秀的&#xff0c;另一种是太平凡的。 我一听呀&#xff1f;那我这岂不是就不优秀了吗&#xff0c;于是毅然决然和女朋友分了手。 人们都说&#xff0c;互联网寒冬来了&#xff0c;这个时候还在大面积招人…

从零开始手写mmo游戏从框架到爆炸(二十一)— 战斗系统二

导航&#xff1a;从零开始手写mmo游戏从框架到爆炸&#xff08;零&#xff09;—— 导航-CSDN博客 上一章&#xff08;从零开始手写mmo游戏从框架到爆炸&#xff08;二十&#xff09;— 战斗系统一-CSDN博客&#xff09;我们只是完成了基本的战斗&#xff0c;速度属性并没有…