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

C++20中的span容器

一.span容器

span 是 C++20 中引入的一个新的标准容器,它用于表示连续的一段内存区间,类似于一个轻量级的只读数组容器。

span 是一个轻量级非拥有式容器,它提供了对连续内存的引用。 span 的主要用途是作为函数参数,可以避免不必要的内存拷贝,并且可以防止悬垂指针和空指针引用的问题

它的定义在头文件 <span> 中,并位于 std 命名空间中。span 包含了一个指向连续内存区域的指针以及它所占用的大小,可以通过它来访问这个内存区域中的元素。

span 主要用于以下场景:

  1. 作为函数的参数,用于指示函数需要处理的数据范围;
  2. 作为类的成员变量,用于表示对象所管理的内存区域;
  3. 作为数组的视图,用于访问数组的一部分

二.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 中新增的一个轻量级容器,用于表示一段连续的内存区域,它不负责管理内存空间,也不会拥有所指向内存的所有权,只是提供一种方便的方式来操作内存区域,因此可以看做是一个只读的“裸指针”。

arrayvector 相比,span主要区别在于它不拥有自己的存储空间,而是引用了另一个数组或容器的内存空间。因此,当我们需要使用一个连续的内存块时,可以使用 span 来代替 arrayvector

具体来说,array 是一个固定大小的数组容器,其大小在编译时就确定了,不能动态改变。vector 是一个动态增长的数组容器,可以动态分配内存,并在需要时扩大容量。而 span 是一个非拥有型的容器,可以看作是一个指向连续内存区域的引用,可以指向任何类型的元素。

在使用方面,arrayvector 可以用来存储数据,并通过下标或迭代器来访问其中的元素;span 则更多地用来表示一段内存区域并提供类似于迭代器的操作来访问其中的元素(就是 只读),如 beginendrbeginrend 等。

总之,spanarrayvector 三者各有所长,可以根据实际需求来选择使用。

2. span 与 数组指针的区别

在C++中,数组和指针是密不可分的,它们常常被一起使用。然而,数组和指针不是相同的东西,它们有自己的属性和限制。同样地,span和指针也有很多区别,这里列举几点:

  1. span是一个封装了数组指针和长度的轻量级容器,它提供了对数组的安全访问。指针只是一个指向内存位置的地址,没有长度信息。因此,使用指针时需要显式地传递长度信息,否则可能会导致缓冲区溢出等问题。

  2. span支持范围操作,它可以使用STL中的算法和其他支持范围操作的库进行操作。指针只能通过指针运算和下标操作来访问和操作数据。

  3. span是可传递性的,可以传递到函数中作为参数,而指针不能。这是因为在函数中传递指针时,我们必须显式地传递指针所指向的内存块的大小,否则函数无法确定内存块的大小。

  4. span是一个类模板,可以指定数据类型和长度类型。指针只能指向特定类型的数据。

总的来说,span比指针更安全,更灵活,更易于使用,是一种更好的数组容器类型。

五.span的优点

std::span 的主要优点如下:

  1. 轻量级:std::span 本身只是一个轻量级的非拥有式容器,没有自己的内存管理,因此可以在不分配内存的情况下轻松地传递和操作数据。同时,std::span 的内存布局与原始数组相同,因此不需要进行数据的复制或重排。

  2. 安全性:std::span 具有边界检查机制,可以避免访问越界等错误,从而提高代码的安全性。

  3. 可组合性:std::span 可以与其他容器类型进行组合,例如可以从 std::vectorstd::array 中创建 std::span,或将 std::span 转换为 std::vectorstd::array

  4. 易于扩展:由于 std::span 只是一个非拥有式容器,因此可以轻松地将其用作接口的一部分,并以此扩展接口的功能。

总之,std::span 是一个非常实用的工具,可以方便地对数据进行访问和处理,同时也可以提高代码的可读性、可维护性和安全性。

具体一些相关的信息见:std::span - cppreference.com

相关文章:

C++20中的span容器

一.span容器 span 是 C20 中引入的一个新的标准容器&#xff0c;它用于表示连续的一段内存区间&#xff0c;类似于一个轻量级的只读数组容器。 span 是一个轻量级的非拥有式容器&#xff0c;它提供了对连续内存的引用。 span 的主要用途是作为函数参数&#xff0c;可以避免不…...

codeforces周赛div3#855记录

目录 总结 一&#xff0c;A. Is It a Cat? 二&#xff0c;B. Count the Number of Pairs 三&#xff0c;C1. Powering the Hero (easy version) 四&#xff0c;C2. Powering the Hero (hard version) 总结 真羡慕ACM校队的同学&#xff0c;能AC七八题&#xff0c;甚至ak …...

2022年考研结果已出,你上岸了吗?

官方公布&#xff1a;2022年考研人数为457万。 2月20号左右&#xff0c;全国考研分数已经陆续公布&#xff0c;现在已经过去一周左右的时间了&#xff0c;你上岸了吗&#xff0c;还是在等调剂&#xff0c;或者已经知道落榜不知道何去何从&#xff1f; 考研的热潮在近几年席卷…...

2023 工业互联网平台:智慧制硅厂 Web SCADA 生产线

我国目前是全球最大的工业硅生产国、消费国和贸易国&#xff0c;且未来该产业的主要增量也将来源于我国。绿色低碳发展已成为全球大趋势和国际社会的共识&#xff0c;随着我国“双碳”目标的推进&#xff0c;光伏产业链快速发展&#xff0c;在光伏装机需求的带动下&#xff0c;…...

6-2 SpringCloud快速开发入门:声明式服务消费 Feign实现消费者

声明式服务消费 Feign实现消费者 使用 Feign实现消费者&#xff0c;我们通过下面步骤进行&#xff1a; 第一步&#xff1a;创建普通 Spring Boot工程 第二步&#xff1a;添加依赖 <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】控制自己的手机拍照,并自动发送到邮箱

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 今天这个案例&#xff0c;就是控制自己的摄像头拍照&#xff0c; 并且把拍下来的照片&#xff0c;通过邮件发到自己的邮箱里。 想完成今天的这个案例&#xff0c;只要记住一个重点&#xff1a;你需要一个摄像头 思路…...

八股文(二)

一、 实现深拷贝和浅拷贝 1.深拷贝 function checkType(any) {return Object.prototype.toString.call(any).slice(8, -1) }//判断拷贝的要进行深拷贝的是数组还是对象&#xff0c;是数组的话进行数组拷贝&#xff0c;对象的话进行对象拷贝 //如果获得的数据是可遍历的&#…...

在CANoe/CANalyzer中观察CAN Message报文的周期Cycle

案例背景&#xff1a; 该篇博文将告诉您&#xff0c;如何直观的&#xff0c;图示化的&#xff0c;查看CAN网络中各CAN Message报文的周期变化。 优质博文推荐阅读&#xff08;单击下方链接&#xff0c;即可跳转&#xff09;&#xff1a; Vector工具链 CAN Matrix DBC CAN M…...

Linux命令·ls

ls命令是linux下最常用的命令。ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单。 通过ls 命令不仅可以查看linux文件夹包含的文件而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息…...

Mysql InnoDB 存储引擎笔记

1 存储引擎 简介 Mysql 存储引擎有多种&#xff1a;包括 MyISAM、InnoDB 和 Memory。 其中MyISAM 和 INNODB 的区别&#xff1a; 事务安全&#xff08;MyISAM不支持事务&#xff0c;INNODB支持事务&#xff09;&#xff1b;外键 MyISAM 不支持外键&#xff0c; INNODB支持外…...

智慧工地AI视频分析系统 opencv

智慧工地AI视频分析系统通过pythonopencv网络模型图像识别技术&#xff0c;智慧工地AI视频分析算法自动识别现场人员穿戴是否合规。本算法模型中用到opencv技术&#xff0c;OpenCV基于C实现&#xff0c;同时提供python, Ruby, Matlab等语言的接口。OpenCV-Python是OpenCV的Pyth…...

小红书「高效达人筛选攻略」

三八女神节降临&#xff0c;诸多品牌纷纷开启铺垫预热&#xff0c;在各大平台借势宣传。而聚集庞大年轻女性消费群体的小红书&#xff0c;对“她营销”的重要性不言而喻。节点序幕拉开&#xff0c;面对海量达人信息&#xff0c;如何提前积草屯粮、高效备战&#xff1f; 本期千瓜…...

大话数据结构-线性表

1 定义 线性表是零个或多个数据元素的有限序列。 2 抽象数据类型 ADT 线性表(List)Data&#xff1a;线性表的数据对象集合为{al,a2,a3,....an}&#xff0c;每个元素的类型均为DataType。其中&#xff0c;除第一个元素a1外&#xff0c;每一个元素有且只有一个直接前驱元素&…...

分布式缓存 Memcached Linux 系统安装

1.Memcached简介 Memcached是一个开源、高性能&#xff0c;将数据分布于内存中并使用key-value存储结构的缓存系统。它通过在内存中缓存数据来减少向数据库的频繁访问连接的次数&#xff0c;可以提高动态、数据库驱动之类网站的运行速度。 Memcached在使用是比较简单的&#…...

【数据结构】链表:看我如何顺藤摸瓜

&#x1f451;专栏内容&#xff1a;数据结构⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;日拱一卒&#xff0c;功不唐捐 文章目录一、前言二、链表1、定义2、单链表Ⅰ、新建一个节点Ⅱ、内存泄漏Ⅲ、插入一个节点Ⅳ、销毁所有节点Ⅴ、反转一个链表3、…...

linux shell 入门学习笔记18 函数开发

概念 函数就是将你需要执行的shell命令组合起来&#xff0c;组成一个函数体。一个完整的函数包括函数头和函数体&#xff0c;其中函数名就是函数的名字。 优点 将相同的程序&#xff0c;定义&#xff0c;封装为一个函数&#xff0c;能减少程序的代码数量&#xff0c;提高开发…...

如何最巧妙回答HR面试“送命题”:你为什么离开上家公司?

一 HR面试存在“送命题”? 一个资深HR朋友聊到,他最近pass掉一个名校高材生。 其实洽谈过程还比较愉悦,小姑娘名校毕业,落落大方,薪酬要求比较合理,各方面都比较符合,最后就在决定要录用时,HR朋友随口问了句 “你为什么离开上家公司?”,小姑娘也是随口说了句“我不喜…...

注意力机制详解系列(五):分支与时间注意力机制

&#x1f468;‍&#x1f4bb;作者简介&#xff1a; 大数据专业硕士在读&#xff0c;CSDN人工智能领域博客专家&#xff0c;阿里云专家博主&#xff0c;专注大数据与人工智能知识分享&#xff0c;公众号&#xff1a;GoAI的学习小屋&#xff0c;免费分享书籍、简历、导图等资料&…...

创宇盾重保经验分享,看政府、央企如何防护?

三月重保已经迫近&#xff0c;留给我们的准备时间越来越少&#xff0c;综合近两年三月重保经验及数据总结&#xff0c;知道创宇用实际案例的防护效果说话&#xff0c;深入解析为何创宇盾可以在历次重保中保持“零事故”成绩&#xff0c;受到众多部委、政府、央企/国企客户的青睐…...

软件测试面试汇总

在浏览器中输入 URL&#xff0c;回车后发生了什么&#xff1f; 在浏览器中输入URL并按下回车键后&#xff0c;大致流程如下&#xff1a; 1、浏览器解析 URL&#xff0c;提取出协议&#xff08;例如HTTP、HTTPS)、主机名和路径等信息。 2、浏览器查找该URL的缓存记录&#xff0…...

空指针,野指针

空指针在C/C中&#xff0c;空指针&#xff08;null pointer&#xff09;是指向内存地址0的指针变量。NULL在C/C中的定义为&#xff1a;#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif #endif从上面的代码定义中&#xff0c;我们可以发现在C…...

Mysql Nested-Loop Join算法和MRR

MySQL8之前仅支持一种join 算法—— nested loop&#xff0c;在 MySQL8 中推出了一种新的算法 hash join&#xff0c;比 nested loop 更加高效。&#xff08;后面有时间介绍这种join算法&#xff09; 1、mysql驱动表与被驱动表及join优化 先了解在join连接时哪个表是驱动表&a…...

Spark 广播/累加

Spark 广播/累加广播变量普通变量广播分布式数据集广播克制 Shuffle强制广播配置项Join Hintsbroadcast累加器Spark 提供了两类共享变量&#xff1a;广播变量&#xff08;Broadcast variables&#xff09;/累加器&#xff08;Accumulators&#xff09; 广播变量 创建广播变量…...

飞天云动,站在下一个商业时代的门口

ChatGPT的爆火让AIGC再度成为热词&#xff0c;随之而来的是对其商业化的畅想——不是ChatGPT自身如何盈利&#xff0c;而是它乃至整个AIGC能给现在的商业环境带来多大改变。 这不由得令人想起另一个同样旨在改变世界的概念&#xff0c;元宇宙。不同的是&#xff0c;元宇宙更侧…...

上海分时电价机制调整对储能项目的影响分析

安科瑞 耿敏花 2022年12月16日&#xff0c;上海市发改委发布《关于进一步完善我市分时电价机制有关事项的通知》(沪发改价管〔2022〕50号)。通知明确上海分时电价机制&#xff0c;一般工商业及其他两部制、大工业两部制用电夏季&#xff08;7、8、9月&#xff09;和冬季&#x…...

产品新人如何快速上手工作

三百六十行&#xff0c;行行出产品经理&#xff1a;上至封神的乔布斯&#xff0c;下至卖鸡蛋罐饼的阿姨&#xff0c;他们对如何打造自己的产品都会有一套完整的产品思路&#xff0c;这也是为什么说“人人都是产品经理”。这个看似光鲜的“经理”有时也会被戏称产品汪&#xff0…...

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初始化&#xff1a;缺省的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 {// 如果文件夹不存在&#xff0c;则建立新文件夹(new File(newPath)).mkdirs();//读取整个文件…...

邢台市政/外贸seo推广

开头 大家好&#xff0c;我是G哥&#xff0c;目前人在荆州办事&#xff0c;但是干货还是要安排上&#xff01; 国外有一个爆火的开发人员学习路线&#xff0c;目前已经在 Github收获了 131 k star&#xff0c;Star 数量在 Github 所有仓库中排名第 9 。这个仓库有多火就不用说…...

武汉平价网站建设/网络seo是什么工作

链接&#xff1a;https://ac.nowcoder.com/acm/contest/5646/J来源&#xff1a;牛客网题目描述对输入的字符串进行排序后输出输入描述:多个测试用例&#xff0c;每个测试用例一行。每行通过,隔开&#xff0c;有n个字符&#xff0c;n&#xff1c;100输出描述:对于每组用例输出一…...

网站建设推广者怎样找到客户/广州关键词快速排名

Bluemix是IBM推出的开放的PaaS云平台&#xff0c;包含大量平台和软件服务&#xff0c;旨在帮助开发者实现一站式地应用开发与部署管理。 2016年&#xff0c;Bluemix面向开发者推出了基于超级账本Fabric的区块链服务&#xff0c;供全球的区块链爱好者使用。用户可以通过访问http…...

做医疗网站建设/网络营销推广要求

init()方法中返回的this指向init的实例对象&#xff0c;而init.prototype等于jQuery.prototype&#xff0c;所以也是jQuery的实例对象&#xff1b; 返回this是为了实现链式调用...

茂名网站建设解决方案/今日新闻快讯10条

Backup Exec 2012 相对之前的版本2010有了很大的变化,最为明显的就是管理控制台界面。管理界面包括"主页"、"备份和还原"、"存储"、"报告",以及“Backup Exec ” 选项按钮.相比早起的BE2010 各小版本界面也更美观了。1. 软件组成ISO 文…...