C++20中的span容器
一.span容器
span
是 C++20 中引入的一个新的标准容器,它用于表示连续的一段内存区间,类似于一个轻量级的只读数组容器。
span
是一个轻量级的非拥有式容器,它提供了对连续内存的引用。 span
的主要用途是作为函数参数,可以避免不必要的内存拷贝,并且可以防止悬垂指针和空指针引用的问题。
它的定义在头文件 <span>
中,并位于 std
命名空间中。span
包含了一个指向连续内存区域的指针以及它所占用的大小,可以通过它来访问这个内存区域中的元素。
span
主要用于以下场景:
- 作为函数的参数,用于指示函数需要处理的数据范围;
- 作为类的成员变量,用于表示对象所管理的内存区域;
- 作为数组的视图,用于访问数组的一部分
二.span的用法
下面是几种 span 的用法示例:
1.将数组转换为 span:
int arr[] = {1, 2, 3, 4, 5};
span<int> s(arr, 5);
这里将一个整型数组 arr
转换为 span 类型,并使用数组首地址和元素个数作为参数。
2.使用 span 来遍历一个容器:
vector<int> vec = {1, 2, 3, 4, 5};
for (auto&& x : span(vec)) {cout << x << " ";
}
这里使用 span(vec)
来构造一个 span 对象,遍历其中的元素并输出。
3.使用 span 来获取子序列:
int arr[] = {1, 2, 3, 4, 5};
span<int> s(arr, 5);
auto s1 = s.subspan(1, 3);
这里将一个 span 对象 s
分割为从第 1 个元素开始,长度为 3 的子序列,并将结果存储到 s1
中。
4.将 span 转换为其他容器类型:
int arr[] = {1, 2, 3, 4, 5};
span<int> s(arr, 5);
vector<int> vec(s.begin(), s.end());
这里使用 s.begin()
和 s.end()
将 span 对象 s
转换为迭代器范围,并使用这个迭代器范围构造一个 vector 容器 vec
。
三.span的底层原理
下面为 span的简化版源码,用于展示其基本实现:
template<typename T, std::size_t Extent = std::dynamic_extent>
class span {
public:// 定义迭代器类型using iterator = T*;using const_iterator = const T*;// 构造函数constexpr span() noexcept : data_(nullptr), size_(0) {}constexpr span(T* ptr, std::size_t count) : data_(ptr), size_(count) {}template <std::size_t N>constexpr span(T(&arr)[N]) noexcept : data_(arr), size_(N) {}template <typename Container>constexpr span(Container& c) noexcept : data_(c.data()), size_(c.size()) {}// 拷贝构造函数和拷贝赋值运算符constexpr span(const span& other) noexcept = default;span& operator=(const span& other) noexcept = default;// 访问元素和迭代器操作constexpr T* data() const noexcept { return data_; }constexpr std::size_t size() const noexcept { return size_; }constexpr bool empty() const noexcept { return size_ == 0; }constexpr T& operator[](std::size_t idx) const { return data_[idx]; }constexpr T& front() const { return data_[0]; }constexpr T& back() const { return data_[size_-1]; }constexpr iterator begin() const noexcept { return data_; }constexpr iterator end() const noexcept { return data_ + size_; }constexpr const_iterator cbegin() const noexcept { return data_; }constexpr const_iterator cend() const noexcept { return data_ + size_; }private:T* data_; // 元素指针std::size_t size_; // 元素数量
};
具体实现方式是通过指针来引用连续的一段内存,从而实现 span 的基本功能。由于 span 没有实际的内存所有权,所以它不能拥有或释放内存。它只是提供了对现有内存块的访问。
标准库中的 span 还提供了一些其他的功能,比如对子区间的切片和子区间的迭代器等。实际的实现可能会更加复杂,但其基本的思想是一致的。
四.span 与 array ,vector ,数组指针 的区别
1. span 与 array ,vector的区别
span
是 C++20 中新增的一个轻量级容器,用于表示一段连续的内存区域,它不负责管理内存空间,也不会拥有所指向内存的所有权,只是提供一种方便的方式来操作内存区域,因此可以看做是一个只读的“裸指针”。
与 array
和 vector
相比,span
的主要区别在于它不拥有自己的存储空间,而是引用了另一个数组或容器的内存空间。因此,当我们需要使用一个连续的内存块时,可以使用 span
来代替 array
或 vector
。
具体来说,array
是一个固定大小的数组容器,其大小在编译时就确定了,不能动态改变。vector
是一个动态增长的数组容器,可以动态分配内存,并在需要时扩大容量。而 span
是一个非拥有型的容器,可以看作是一个指向连续内存区域的引用,可以指向任何类型的元素。
在使用方面,array
和 vector
可以用来存储数据,并通过下标或迭代器来访问其中的元素;span
则更多地用来表示一段内存区域,并提供类似于迭代器的操作来访问其中的元素(就是 只读),如 begin
、end
、rbegin
、rend
等。
总之,span
、array
和 vector
三者各有所长,可以根据实际需求来选择使用。
2. span 与 数组指针的区别
在C++中,数组和指针是密不可分的,它们常常被一起使用。然而,数组和指针不是相同的东西,它们有自己的属性和限制。同样地,span
和指针也有很多区别,这里列举几点:
span
是一个封装了数组指针和长度的轻量级容器,它提供了对数组的安全访问。指针只是一个指向内存位置的地址,没有长度信息。因此,使用指针时需要显式地传递长度信息,否则可能会导致缓冲区溢出等问题。
span
支持范围操作,它可以使用STL中的算法和其他支持范围操作的库进行操作。指针只能通过指针运算和下标操作来访问和操作数据。
span
是可传递性的,可以传递到函数中作为参数,而指针不能。这是因为在函数中传递指针时,我们必须显式地传递指针所指向的内存块的大小,否则函数无法确定内存块的大小。
span
是一个类模板,可以指定数据类型和长度类型。指针只能指向特定类型的数据。
总的来说,span
比指针更安全,更灵活,更易于使用,是一种更好的数组容器类型。
五.span的优点
std::span
的主要优点如下:
轻量级:
std::span
本身只是一个轻量级的非拥有式容器,没有自己的内存管理,因此可以在不分配内存的情况下轻松地传递和操作数据。同时,std::span
的内存布局与原始数组相同,因此不需要进行数据的复制或重排。安全性:
std::span
具有边界检查机制,可以避免访问越界等错误,从而提高代码的安全性。可组合性:
std::span
可以与其他容器类型进行组合,例如可以从std::vector
或std::array
中创建std::span
,或将std::span
转换为std::vector
或std::array
。易于扩展:由于
std::span
只是一个非拥有式容器,因此可以轻松地将其用作接口的一部分,并以此扩展接口的功能。
总之,std::span
是一个非常实用的工具,可以方便地对数据进行访问和处理,同时也可以提高代码的可读性、可维护性和安全性。
具体一些相关的信息见:std::span - cppreference.com
相关文章:
C++20中的span容器
一.span容器 span 是 C20 中引入的一个新的标准容器,它用于表示连续的一段内存区间,类似于一个轻量级的只读数组容器。 span 是一个轻量级的非拥有式容器,它提供了对连续内存的引用。 span 的主要用途是作为函数参数,可以避免不…...
codeforces周赛div3#855记录
目录 总结 一,A. Is It a Cat? 二,B. Count the Number of Pairs 三,C1. Powering the Hero (easy version) 四,C2. Powering the Hero (hard version) 总结 真羡慕ACM校队的同学,能AC七八题,甚至ak …...
2022年考研结果已出,你上岸了吗?
官方公布:2022年考研人数为457万。 2月20号左右,全国考研分数已经陆续公布,现在已经过去一周左右的时间了,你上岸了吗,还是在等调剂,或者已经知道落榜不知道何去何从? 考研的热潮在近几年席卷…...
2023 工业互联网平台:智慧制硅厂 Web SCADA 生产线
我国目前是全球最大的工业硅生产国、消费国和贸易国,且未来该产业的主要增量也将来源于我国。绿色低碳发展已成为全球大趋势和国际社会的共识,随着我国“双碳”目标的推进,光伏产业链快速发展,在光伏装机需求的带动下,…...
6-2 SpringCloud快速开发入门:声明式服务消费 Feign实现消费者
声明式服务消费 Feign实现消费者 使用 Feign实现消费者,我们通过下面步骤进行: 第一步:创建普通 Spring Boot工程 第二步:添加依赖 <dependencies><!--SpringCloud 集成 eureka 客户端的起步依赖--><dependency>…...
Git-学习笔记01【Git简介及安装使用】
Java后端 学习路线 笔记汇总表【黑马-传智播客】Git-学习笔记01【Git简介及安装使用】Git-学习笔记02【Git连接远程仓库】Git-学习笔记03【Git分支】目录 01-git的历史 02-git和svn的对比 03-git的安装 04-向本地仓库中添加文件 05-修改文件内容并提交 06-删除本地仓库中…...
【Python】控制自己的手机拍照,并自动发送到邮箱
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 今天这个案例,就是控制自己的摄像头拍照, 并且把拍下来的照片,通过邮件发到自己的邮箱里。 想完成今天的这个案例,只要记住一个重点:你需要一个摄像头 思路…...
八股文(二)
一、 实现深拷贝和浅拷贝 1.深拷贝 function checkType(any) {return Object.prototype.toString.call(any).slice(8, -1) }//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 //如果获得的数据是可遍历的&#…...
在CANoe/CANalyzer中观察CAN Message报文的周期Cycle
案例背景: 该篇博文将告诉您,如何直观的,图示化的,查看CAN网络中各CAN Message报文的周期变化。 优质博文推荐阅读(单击下方链接,即可跳转): Vector工具链 CAN Matrix DBC CAN M…...
Linux命令·ls
ls命令是linux下最常用的命令。ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单。 通过ls 命令不仅可以查看linux文件夹包含的文件而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息…...
Mysql InnoDB 存储引擎笔记
1 存储引擎 简介 Mysql 存储引擎有多种:包括 MyISAM、InnoDB 和 Memory。 其中MyISAM 和 INNODB 的区别: 事务安全(MyISAM不支持事务,INNODB支持事务);外键 MyISAM 不支持外键, INNODB支持外…...
智慧工地AI视频分析系统 opencv
智慧工地AI视频分析系统通过pythonopencv网络模型图像识别技术,智慧工地AI视频分析算法自动识别现场人员穿戴是否合规。本算法模型中用到opencv技术,OpenCV基于C实现,同时提供python, Ruby, Matlab等语言的接口。OpenCV-Python是OpenCV的Pyth…...
小红书「高效达人筛选攻略」
三八女神节降临,诸多品牌纷纷开启铺垫预热,在各大平台借势宣传。而聚集庞大年轻女性消费群体的小红书,对“她营销”的重要性不言而喻。节点序幕拉开,面对海量达人信息,如何提前积草屯粮、高效备战? 本期千瓜…...
大话数据结构-线性表
1 定义 线性表是零个或多个数据元素的有限序列。 2 抽象数据类型 ADT 线性表(List)Data:线性表的数据对象集合为{al,a2,a3,....an},每个元素的类型均为DataType。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素&…...
分布式缓存 Memcached Linux 系统安装
1.Memcached简介 Memcached是一个开源、高性能,将数据分布于内存中并使用key-value存储结构的缓存系统。它通过在内存中缓存数据来减少向数据库的频繁访问连接的次数,可以提高动态、数据库驱动之类网站的运行速度。 Memcached在使用是比较简单的&#…...
【数据结构】链表:看我如何顺藤摸瓜
👑专栏内容:数据结构⛪个人主页:子夜的星的主页💕座右铭:日拱一卒,功不唐捐 文章目录一、前言二、链表1、定义2、单链表Ⅰ、新建一个节点Ⅱ、内存泄漏Ⅲ、插入一个节点Ⅳ、销毁所有节点Ⅴ、反转一个链表3、…...
linux shell 入门学习笔记18 函数开发
概念 函数就是将你需要执行的shell命令组合起来,组成一个函数体。一个完整的函数包括函数头和函数体,其中函数名就是函数的名字。 优点 将相同的程序,定义,封装为一个函数,能减少程序的代码数量,提高开发…...
如何最巧妙回答HR面试“送命题”:你为什么离开上家公司?
一 HR面试存在“送命题”? 一个资深HR朋友聊到,他最近pass掉一个名校高材生。 其实洽谈过程还比较愉悦,小姑娘名校毕业,落落大方,薪酬要求比较合理,各方面都比较符合,最后就在决定要录用时,HR朋友随口问了句 “你为什么离开上家公司?”,小姑娘也是随口说了句“我不喜…...
注意力机制详解系列(五):分支与时间注意力机制
👨💻作者简介: 大数据专业硕士在读,CSDN人工智能领域博客专家,阿里云专家博主,专注大数据与人工智能知识分享,公众号:GoAI的学习小屋,免费分享书籍、简历、导图等资料&…...
创宇盾重保经验分享,看政府、央企如何防护?
三月重保已经迫近,留给我们的准备时间越来越少,综合近两年三月重保经验及数据总结,知道创宇用实际案例的防护效果说话,深入解析为何创宇盾可以在历次重保中保持“零事故”成绩,受到众多部委、政府、央企/国企客户的青睐…...
软件测试面试汇总
在浏览器中输入 URL,回车后发生了什么? 在浏览器中输入URL并按下回车键后,大致流程如下: 1、浏览器解析 URL,提取出协议(例如HTTP、HTTPS)、主机名和路径等信息。 2、浏览器查找该URL的缓存记录࿰…...
空指针,野指针
空指针在C/C中,空指针(null pointer)是指向内存地址0的指针变量。NULL在C/C中的定义为:#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif #endif从上面的代码定义中,我们可以发现在C…...
Mysql Nested-Loop Join算法和MRR
MySQL8之前仅支持一种join 算法—— nested loop,在 MySQL8 中推出了一种新的算法 hash join,比 nested loop 更加高效。(后面有时间介绍这种join算法) 1、mysql驱动表与被驱动表及join优化 先了解在join连接时哪个表是驱动表&a…...
Spark 广播/累加
Spark 广播/累加广播变量普通变量广播分布式数据集广播克制 Shuffle强制广播配置项Join Hintsbroadcast累加器Spark 提供了两类共享变量:广播变量(Broadcast variables)/累加器(Accumulators) 广播变量 创建广播变量…...
飞天云动,站在下一个商业时代的门口
ChatGPT的爆火让AIGC再度成为热词,随之而来的是对其商业化的畅想——不是ChatGPT自身如何盈利,而是它乃至整个AIGC能给现在的商业环境带来多大改变。 这不由得令人想起另一个同样旨在改变世界的概念,元宇宙。不同的是,元宇宙更侧…...
上海分时电价机制调整对储能项目的影响分析
安科瑞 耿敏花 2022年12月16日,上海市发改委发布《关于进一步完善我市分时电价机制有关事项的通知》(沪发改价管〔2022〕50号)。通知明确上海分时电价机制,一般工商业及其他两部制、大工业两部制用电夏季(7、8、9月)和冬季&#x…...
产品新人如何快速上手工作
三百六十行,行行出产品经理:上至封神的乔布斯,下至卖鸡蛋罐饼的阿姨,他们对如何打造自己的产品都会有一套完整的产品思路,这也是为什么说“人人都是产品经理”。这个看似光鲜的“经理”有时也会被戏称产品汪࿰…...
Linux: ARM GIC仅中断CPU 0问题分析
文章目录1. 前言2. 分析背景3. 问题4. 分析4.1 ARM GIC 中断芯片简介4.1.1 中断类型和分布4.1.2 拓扑结构4.2 问题根因4.2.1 设置GIC SPI中断的CPU亲和性4.2.2 GIC初始化:缺省的CPU亲和性4.2.2.1 boot CPU亲和性初始化流程4.2.2.1 其它非 boot CPU亲和性初始化流程5…...
第20篇:Java运算符全面总结(系列二)
目录 4、逻辑运算符 4.1 逻辑运算符 4.2 代码示例 5、赋值运算符 5.1 赋值运算符...
OpenCV4.x图像处理实例-OpenCV两小时快速入门(基于Python)
OpenCV两小时快速入门(基于Python) 文章目录 OpenCV两小时快速入门(基于Python)1、OpenCV环境安装2、图像读取与显示3、图像像素访问、操作与ROI4、图像缩放5、几何变换5.1 平移5.2 旋转6、基本绘图6.1 绘制直线6.2 绘制圆6.3 绘制矩形6.4 绘制文本7、剪裁图像8、图像平滑与…...
怎么做网站dreamwave/杭州网站建设 seo
复制文件夹中所有内容到指定位置 /*** 复制文件夹下的所有文件到指定目录* param oldPath* param newPath*/public static void copyFolder(String oldPath, String newPath) {try {// 如果文件夹不存在,则建立新文件夹(new File(newPath)).mkdirs();//读取整个文件…...
邢台市政/外贸seo推广
开头 大家好,我是G哥,目前人在荆州办事,但是干货还是要安排上! 国外有一个爆火的开发人员学习路线,目前已经在 Github收获了 131 k star,Star 数量在 Github 所有仓库中排名第 9 。这个仓库有多火就不用说…...
武汉平价网站建设/网络seo是什么工作
链接:https://ac.nowcoder.com/acm/contest/5646/J来源:牛客网题目描述对输入的字符串进行排序后输出输入描述:多个测试用例,每个测试用例一行。每行通过,隔开,有n个字符,n<100输出描述:对于每组用例输出一…...
网站建设推广者怎样找到客户/广州关键词快速排名
Bluemix是IBM推出的开放的PaaS云平台,包含大量平台和软件服务,旨在帮助开发者实现一站式地应用开发与部署管理。 2016年,Bluemix面向开发者推出了基于超级账本Fabric的区块链服务,供全球的区块链爱好者使用。用户可以通过访问http…...
做医疗网站建设/网络营销推广要求
init()方法中返回的this指向init的实例对象,而init.prototype等于jQuery.prototype,所以也是jQuery的实例对象; 返回this是为了实现链式调用...
茂名网站建设解决方案/今日新闻快讯10条
Backup Exec 2012 相对之前的版本2010有了很大的变化,最为明显的就是管理控制台界面。管理界面包括"主页"、"备份和还原"、"存储"、"报告",以及“Backup Exec ” 选项按钮.相比早起的BE2010 各小版本界面也更美观了。1. 软件组成ISO 文…...