【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 被推导为 int
    double 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) {} // 初始化栈顶索引为-1

    void 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++程序员提供了丰富的数据结构和算法,极大地提高了程序开发的效率和质量。


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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux系列讲解 —— 【Vim编辑器】在Ubuntu18.04中安装新版Vim

平时用的电脑系统是Ubuntu18.04&#xff0c;使用apt安装VIM的默认版本是8.0。如果想要安装新版的Vim编辑器&#xff0c;只能下载Vim源码后进行编译安装。 目录 1. 下载Vim源码2. 编译3. 安装4. 遇到的问题4.1 打开vim后&#xff0c;文本开头有乱码现象。4.2 在Vim编辑器中&…

通信入门系列——锁相环、平方环、Costas环

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、锁相环 1、压控振荡…

精酿啤酒:麦芽与啤酒花搭配的奥秘

麦芽和啤酒花是啤酒酿造过程中不可或缺的原料&#xff0c;它们的风味和特点对啤酒的口感和品质产生着深远的影响。Fendi Club啤酒在麦芽与啤酒花的搭配方面有着与众不同的技巧和见解&#xff0c;让啤酒的口感更加丰富和迷人。 首先&#xff0c;麦芽的选择是啤酒酿造的关键之一。…

C语言特殊函数

静态函数 背景知识&#xff1a;普通函数都是跨文件可见的&#xff0c;即在文件 a.c 中定义的函数可以在 b.c 中使用。 静态函数&#xff1a;只能在定义的文件内可见的函数&#xff0c;称为静态函数。 语法 staitc void f(void) // 在函数头前面增加关键字 static &#xff…

2024.2.22 C++QT 作业

思维导图 练习题 1>完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面。如果账…

2024年开发者的最好选择!!没有之一

中国银河证券1月23日明确指出&#xff1a;鸿蒙应用将在2024年迎来爆发。 2024年Q2推出开发者Beta版&#xff0c;2024年Q4推出商用版。今年年终将有 5000 款应用完成原生鸿蒙开发&#xff0c;未来支持 50 万款应用。覆盖便捷生活、出行文旅、金融便利、社交资讯、生产力工具、影…

Stable Diffusion 3 Early Preview发布

2月22日&#xff0c;Stability AI 发布了 Stable Diffusion 3 early preview&#xff0c;这是一种开放权重的下一代图像合成模型。据报道&#xff0c;它继承了其前身&#xff0c;生成了详细的多主题图像&#xff0c;并提高了文本生成的质量和准确性。这一简短的公告并未附带公开…

节假日效应prophet预测模型和节假日识别错误

节假日效应是指在特定的节假日或纪念日期间&#xff0c;人们的行为和活动发生变化&#xff0c;从而影响到相应的时间序列数据&#xff08;股票或者其他&#xff09;。这种效应可能在多个领域产生影响&#xff0c;包括销售、交通、能源消耗等。 完整代码和数据可关注gzh’financ…

[算法沉淀记录] 排序算法 —— 归并排序

排序算法 —— 归并排序 算法介绍 归并排序是一种分治算法&#xff0c;由约翰冯诺伊曼在1945年发明。它的工作原理是将未排序的列表划分为n个子列表&#xff0c;每个子列表包含一个元素(包含一个元素的列表被认为是有序的)&#xff0c;然后重复合并子列表以生成新的有序子列表…

最简单方式把jar打包成Windows服务

废话 &#x1f622; 将JAR文件转化为Windows服务是一种高效且常见的Java应用部署策略。这种转变赋予了Java应用程序在Windows操作系统上以无界面后台服务模式运行的能力&#xff0c;从而实现了持续、稳定且可靠的功能提供。这种部署方式不仅提升了应用的可用性&#xff0c…

TreeData 数据查找

TreeData 数据查找 最近做需求的时候遇到了这样的一个需求&#xff0c;Tree组件数据支持查找&#xff0c;而且TreeData的数据层级是无限级的 开始想的事借助UI组件库&#xff08;Ant-design-vue&#xff09;中的Tree组件的相关方法直接实现,看了下api 发现没法实现&#xff0c;…

Java SpringBoot测试OceanBase

对上篇mysql导入到OceanBase中的数据库进行代码测试&#xff0c;写了个demo包含测试方法&#xff0c;在原mysql库中成功执行&#xff0c;迁移到OceanBase时看是否能不修改业务代码而成功执行测试方法&#xff1a; 代码基于SpringBoot MyBastis测试增删改查、批量新增、多表联…

onnx 1.16 doc学习笔记一:ONNX概念

onnx作为一个通用格式&#xff0c;很少有中文教程&#xff0c;因此开一篇文章对onnx 1.16文档进行翻译与进一步解释&#xff0c; onnx 1.16官方文档&#xff1a;https://onnx.ai/onnx/intro/index.html](https://onnx.ai/onnx/intro/index.html)&#xff0c; 如果觉得有收获&am…

【Redis服务搭建】

目录 Redis的修改配置启动以及参数调优Redis的常用基本操作Redis运维监控命令Redis的配置的动态更新和写入Redis的多用户管理Redis的慢日志Redis禁用危险命令和压测工具Redis持久化存储1.Redis的RDB持久化存储2.Redis的AOF持久化存储 Redis的主从复制redis的哨兵实现主从自动切…

信号信号槽

三、信号槽 概念 信号和槽是两种函数&#xff0c;这是Qt在C基础上新增的特性&#xff0c;类似于其他技术中的回调的概念。 信号槽通过程序员提前设定的“约定”&#xff0c;可以实现对象之间的通信&#xff0c;有两个先决条件。 通信的对象都是在QOBject类中派生出来的。 QOBje…

提升App推广效果,从优化落地页开始

在App推广过程中&#xff0c;落地页的转化率一直是推广运营者关注的重点。然而&#xff0c;很多运营者发现&#xff0c;即使使用了相同的工具和模板&#xff0c;别人的效果却远远超出自己。那么&#xff0c;问题到底出在哪里呢&#xff1f;今天&#xff0c;我们就来聊聊如何提升…

便携式气象站的安装注意事项

型号推荐&#xff1a;云境天合TH-BQX9】便携式气象站的安装注意事项包括以下几点&#xff1a; 安装前检查&#xff1a;在安装前&#xff0c;应对便携式气象站进行检查&#xff0c;确保设备的包装完好无损&#xff0c;配件齐全&#xff0c;如气象站传感器、支架、采集器和传输模…

链表和顺序表的优劣分析及其时间、空间复杂度分析

链表和顺序表的优劣分析及其时间、空间复杂度分析 一、链表和顺序表的优劣分析二、算法复杂度<font face "楷体" size 5 color blue>//上面算法的执行次数大致为&#xff1a;F&#xff08;N&#xff09; N^22*N10;   N 10,F(10) 1002010 130次   N 1…

提高学习效率和速度的方法

如下是一些策略和方法来帮助提高学习效率和速度&#xff1a; 1. **主动学习**&#xff1a;主动寻找信息并提出问题&#xff0c;而不是被动接受。这样可以提高您的学习动力和效率。 2. **分块学习**&#xff1a;将复杂的知识点分解成小块&#xff0c;逐一理解和掌握。这种方法可…

unity屏幕受伤特效

//使用用途&#xff1a;同于屏幕掉血的后处理特效 //请结合和脚本&#xff1a;BloodScreen 挂载至摄像机使用本特效 //本特效设计之初未考虑兼容移动设备&#xff0c;请注意//使用说明&#xff1a; //掉血获取此脚本&#xff0c;将showBlood设置为true&#xff0c;如果您需要更…