C++的STL都由什么组成

C++标准模板库(STL)是C++语言的一部分,提供了一系列模板类和函数,旨在帮助程序员处理常见的编程任务,如数据结构和算法操作。
STL主要包括四大组件:
容器(Containers)、
迭代器(Iterators)、
算法(Algorithms)
函数对象(Function objects)。
下面是对这些组件的详细介绍:

1. 容器(Containers)

容器是用来管理某一类对象的集合。STL提供了多种不同类型的容器,每种容器都设计用来管理特定类型的对象集合。

  • 序列容器(Sequence Containers):管理元素的线性排列。

    • vector:动态数组,支持快速随机访问。
    • list:双向链表,支持快速插入和删除。
    • deque:双端队列,两端都可以快速插入和删除。
    • forward_list(C++11):单向链表,效率高于list但只能单向遍历。
    • array(C++11):固定大小数组,支持快速随机访问,大小在编译时确定。
  • 关联容器(Associative Containers):基于键来管理元素的集合。

    • set:元素唯一且自动排序的集合。
    • multiset:元素可以重复且自动排序的集合。
    • map:基于键值对的集合,键唯一且自动排序。
    • multimap:基于键值对的集合,键可以重复且自动排序。
  • 无序关联容器(Unordered Associative Containers)(C++11):基于哈希表的容器,元素不自动排序。

    • unordered_set:元素唯一的集合。
    • unordered_multiset:元素可以重复的集合。
    • unordered_map:基于键值对的集合,键唯一。
    • unordered_multimap:基于键值对的集合,键可以重复。

2. 迭代器(Iterators)

迭代器提供了一种访问容器元素的方法,而不需要了解容器的内部工作原理。它类似于指针,可以用来遍历STL容器中的元素。

  • 迭代器类型
    • 输入迭代器
    • 输出迭代器
    • 前向迭代器
    • 双向迭代器
    • 随机访问迭代器

3. 算法(Algorithms)

STL提供了一系列标准算法,如排序、搜索、修改序列等操作,这些算法通常通过迭代器与容器进行交互。

  • 算法类型
    • 非修改序列算法
    • 修改序列算法
    • 排序和相关操作
    • 通用数值算法

4. 函数对象(Function objects)

函数对象(也称为仿函数)是实现了operator()的类的实例。STL中的函数对象可以用作算法的比较函数、执行特定操作的函数等。

  • 函数对象的分类
    • 算术运算类
    • 关系运算类
    • 逻辑运算类
    • 自定义仿函数

5. 适配器(Adapters)

适配器是一种特殊的容器、迭代器或函数对象,它通过特定的接口对STL提供的其他组件进行封装,以改变其行为。

  • 容器适配器stackqueuepriority_queue
  • 迭代器适配器reverse_iteratorinsert_iteratorstream_iterator
  • 函数适配器bind function(C++11)
    STL是C++中非常强大的一部分,掌握它可以极大地提高编程效率和代码质量。通过结合使用不同的STL组件,可以解决大多数编程问题,并写出既简洁又高效的代码。

一些代码示例
让我们通过具体的代码示例来探讨C++标准模板库(STL)的各个组件及其语法,以及它们解决的问题。

1. 容器(Containers)

vector(动态数组)
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};vec.push_back(6); // 在末尾添加一个元素std::cout << "Vector: ";for(int num : vec) {std::cout << num << " ";}std::cout << "\n";
}

问题解决std::vector提供了一个动态大小的数组。与普通数组相比,它可以在运行时动态地改变大小,非常适合于不知道确切元素数量的情况。

2. 迭代器(Iterators)

使用迭代器遍历vector
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};for(auto it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";}std::cout << "\n";
}

问题解决:迭代器提供了一种统一的方式来访问容器中的元素,不需要关心容器的具体类型。

3. 算法(Algorithms)

sort(排序)
#include <algorithm>
#include <vector>
#include <iostream>int main() {std::vector<int> vec = {5, 3, 4, 1, 2};std::sort(vec.begin(), vec.end());for(int num : vec) {std::cout << num << " ";}std::cout << "\n";
}

问题解决:STL中的算法如std::sort,提供了通用的解决方案,用于执行如排序、搜索等常见操作,而无需手动实现。

4. 函数对象(Function objects)

使用函数对象进行比较
#include <algorithm>
#include <vector>
#include <iostream>struct greater {bool operator()(int a, int b) {return a > b;}
};int main() {std::vector<int> vec = {5, 3, 4, 1, 2};std::sort(vec.begin(), vec.end(), greater());for(int num : vec) {std::cout << num << " ";}std::cout << "\n";
}

问题解决:函数对象允许将行为(如比较)封装在对象中,这使得算法如std::sort能够以通用和灵活的方式执行。

5. 适配器(Adapters)

stack(栈)
#include <stack>
#include <iostream>int main() {std::stack<int> stk;stk.push(1);stk.push(2);stk.push(3);while(!stk.empty()) {std::cout << stk.top() << " ";stk.pop();}std::cout << "\n";
}

问题解决:容器适配器如std::stack提供了特定的数据结构的接口,例如栈(LIFO顺序)。它们使得对这些数据结构的操作更为直观和简洁。

通过这些示例,我们可以看到STL如何提供了一套丰富的工具和抽象,让处理数据结构和算法更加简单和高效。STL的设计允许程序员以通用的方式编写代码,从而提高了代码的复用性和可维护性。

函数对象更加具体的用法

函数对象(也称为仿函数)是一种使用对象模拟函数调用的技术。它们通过重载operator()实现,这让对象可以像函数一样被调用。虽然在日常编程中可能不如普通函数或Lambda表达式那样频繁见到,但函数对象在某些情况下非常有用,特别是在需要对象保持状态或需要多次重用操作逻辑时。下面是一些函数对象的其他示例和使用场景:

1. 带状态的函数对象

函数对象可以携带状态(即类成员变量的值),这允许它在多次调用之间保持某些信息。

#include <iostream>
#include <vector>
#include <algorithm>class CountIf {
private:int threshold;
public:CountIf(int t) : threshold(t) {}bool operator()(int x) {return x > threshold;}
};int main() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};CountIf countIf5(5); // 创建一个阈值为5的函数对象int count = std::count_if(vec.begin(), vec.end(), countIf5);std::cout << "There are " << count << " numbers greater than 5\n";
}

这个例子中,CountIf函数对象根据构造时给定的阈值来判断整数是否满足条件,并在使用std::count_if算法时携带状态(阈值)。

2. 结合STL算法使用函数对象

函数对象可以与STL算法结合使用,提供自定义的比较逻辑或操作。

#include <iostream>
#include <algorithm>
#include <vector>class Multiply {
public:int operator()(int x) {return x * 2;}
};int main() {std::vector<int> vec = {1, 2, 3, 4, 5};std::transform(vec.begin(), vec.end(), vec.begin(), Multiply());for(int num : vec) {std::cout << num << " ";}std::cout << "\n";
}

在这个例子中,Multiply函数对象被用于std::transform算法中,将向量中的每个元素乘以2。

3. 作为比较函数的函数对象

在需要自定义排序准则时,函数对象可以用作比较函数。

#include <iostream>
#include <algorithm>
#include <vector>class Descend {
public:bool operator()(int a, int b) {return a > b; // 降序排列}
};int main() {std::vector<int> vec = {5, 3, 1, 4, 2};std::sort(vec.begin(), vec.end(), Descend());for(int num : vec) {std::cout << num << " ";}std::cout << "\n";
}

这里,Descend函数对象用于std::sort,实现了一个降序排序。

总结

函数对象提供了一种灵活的方式来封装操作逻辑,可以携带状态,可以重复使用,并且可以被STL算法等接受作为参数的地方使用。通过使用函数对象,可以在C++中实现更复杂和强大的功能。

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

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

相关文章

虚拟机器centos7无法识别yum 命令异常处理笔记

问题现象 启动虚拟机后执行ipconfig 提示未找到该命令,然后执行yum install -y net-tools提示 curl#6 - "Could not resolve host: mirrorlist.centos.org; 未知的错误"的错误 [roothaqdoop~]# ifconfig -bash: ifconfig: 未找到命令 [roothadoop~]# yum install …

以Scala官方提供的方法解读TraversableOnce

代码提供 让我们先来看Scala中提供的一段代码 static List toList$(final TraversableOnce $this) { return $this.toList(); } default List toList() {return (List)this.to(scala.collection.immutable.List..MODULE$.canBuildFrom()); } 上述代码片段是Scala中的两个方…

Android自编译Pixel3内核加入KernelSU

背景 让Pixel3 AOSP Android10 4.9内核用上Kernel SU 环境: Ubuntu 18.04 vm aosp10r2 移植参考官方,和github项目 Commits OnlyTomInSecond/android_kernel_xiaomi_sdm845 (github.com) 这个项目是 LineageOS/android_kernel_xiaomi_sdm845 编译的前提 已经有完整…

超级抽象的前端2

vue3的调用方法失败的原因 function validateConfirm(rule, value, callback) {if (value ! form.password) {callback(new Error(两次输入的密码不一致))} else {callback()}function showAgreement() {dialogVisible.value true}function submitForm() {// 这里是提交表单的…

逆推求期望DP

我的开始的想法&#xff1a;状态设置 dp[i][j] 为玩了 i 个职业 j 个阵营的期望天数&#xff0c;初始值很好解决 dp[1][1]1 &#xff0c;但是有个问题&#xff0c;每对 (i,j) 除了边界那里&#xff0c;会由三个地方来决定这一个(i-1,j-1)(i,j-1)(i-1,j)&#xff0c;所以&#x…

LayUI发送Ajax请求

页面初始化操作 var processData null $(function () {initView();initTable();// test(); })function initView() {layui.use([laydate, form], function () {var laydate layui.laydate;laydate.render({elem: #applyDateTimeRange,type: datetime,range: true});}); }初始…

【spring】 ApplicationListener的使用及原理简析

文章目录 使用示例&#xff1a;原理简析&#xff1a; 前言&#xff1a;ApplicationListener 是spring提供的一个监听器&#xff0c;它可以实现一个简单的发布-订阅功能&#xff0c;用有点外行但最简单通俗的话来解释&#xff1a;监听到主业务在执行到了某个节点之后&#xff0c…

Elasticsearch中可避免的坑

版本定位&#xff1a;7.x 总结的坑&#xff1a; term及terms词条查询时&#xff0c;如果有text及keyword类型&#xff0c;则需加.keywordqueryString全字段搜索时&#xff0c;最好指定字段&#xff1b;并要提前设置好字段mapping&#xff1a;keyword并指定分词器。reindex做数…

【ACM出版】第五届计算机信息和大数据应用国际学术会议(CIBDA 2024)

第五届计算机信息和大数据应用国际学术会议&#xff08;CIBDA 2024&#xff09; 2024 5th International Conference on Computer Information and Big Data Applications 重要信息 大会官网&#xff1a;www.ic-cibda.org 大会时间&#xff1a;2024年3月22-24日 大会地点&#…

Atcoder ABC341 A-D题解

比赛链接:ABC341 Problem A: 先签个到。 #include <bits/stdc.h> using namespace std; int main() {int n;cin>>n;for(int i0;i<n;i)cout<<"10"<<endl;cout<<"1"<<endl;return 0; } Problem B: 继续签。 #i…

week04day03(爬虫 beautifulsoup4、)

一. 使用bs4解析网页 下载bs4 - pip install beautifulsoup4 使用的时候 import bs4专门用于解析网页的第三方库 在使用bs4的时候往往会依赖另一个库lxml pip install lxml 网页代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><…

【Python笔记-设计模式】对象池模式

一、说明 用于管理对象的生命周期&#xff0c;重用已经创建的对象&#xff0c;从而减少资源消耗和创建对象的开销 (一) 解决问题 主要解决频繁创建和销毁对象所带来的性能开销问题。如数据库连接、线程管理、网络连接等&#xff0c;对象的创建和销毁成本相对较高&#xff0c…

冬眠...

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 阿宁生活在一个 nnn 行 mmm 列的字符矩阵中&#xff0c;阿宁打算在第 xxx 行 yyy 列冬眠。 在每一天&#xff0c;都会有 qqq 次行循环移动或列循环移动。 如果是第 zzz 行循环移动&#xff0c;…

IC卡批量加密软件使用

IC卡出厂是默认的密码FFFFFFFFFFFF空白卡&#xff0c;IC卡在门禁、电梯、食堂消费、洗浴一卡通等系统上使用前是需要初始化的&#xff0c;即加密的同时写入基础数据。 为什么要用批量加密软件呢&#xff0c;以为需要加密的卡有几百张&#xff0c;几千张&#xff0c;数量比较多&…

shiro 整合 springmvc 实战及源码详解

序言 前面我们学习了如下内容&#xff1a; 5 分钟入门 shiro 安全框架实战笔记 shiro 整合 spring 实战及源码详解 相信大家对于 shiro 已经有了最基本的认识&#xff0c;这一节我们一起来学习写如何将 shiro 与 springmvc 进行整合。 spring mvc 整合源码 maven 依赖 版…

水务界的“数字蝶变”:水务公司重构自我,开启智慧供水新时代

历经六十余载的稳健前行&#xff0c;某水务公司已发展成为国有一档企业中的供水行业佼佼者&#xff0c;不仅主营业务突出&#xff0c;更拥有完善的产业链条。然而&#xff0c;面对供水业务24小时连续作业的高要求&#xff0c;以及业务管理需求的日益复杂化&#xff0c;公司意识…

Qt中添加Mysql驱动

qt连接mysql报错&#xff1a;QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: available drivers: QSQLITE QODBC QODBC3 QPSQL QPSQL7 - №点缀 - 博客园 (cnblogs.com)

【Django开发】0到1开发美多shop项目:Celery短信和用户注册。全md文档笔记(附代码,已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论django商城项目开发相关知识。本项目利用Django框架开发一套前后端不分离的商城项目&#xff08;4.0版本&#xff09;含代码和文档。功能包括前后端不分离&#xff0c;方便SEO。采用Django Jinja2模板引擎 Vue.js实现…

Python网络爬虫实战:从入门到进阶

Python网络爬虫是一种自动化程序&#xff0c;用于从互联网上抓取、解析和提取数据。这种技术广泛应用于数据分析、机器学习、搜索引擎优化等领域。下面是一个Python网络爬虫的入门到进阶的实战指南&#xff1a; 入门篇 环境准备 安装Python和pip安装必要的库&#xff1a;reque…

突破编程_C++_高级教程(内存管理(1))

1 内存管理基础 C 的内存管理主要涉及如何分配、使用和释放计算机内存&#xff0c;以确保程序的正确运行和性能优化。其重要任务是避免内存泄漏和野指针等问题。 C 的内存管理是一个涉及多个方面和复杂概念的重要主题。正确地管理内存对于编写高效、稳定和安全的程序至关重要。…