C++23 std::mdspan:多维数组处理新利器
文章目录
- 引言
- C++23简介
- std::mdspan的定义与特点
- 定义
- 特点
- std::mdspan的优势
- 零成本抽象的多维数据访问
- 减少内存开销
- 提高代码灵活性
- std::mdspan的应用场景
- 科学计算
- 图形学
- 相关提案
- 示例代码
- 使用动态扩展
- 使用静态和动态扩展
- 总结
引言
在C++的发展历程中,每一个新版本都带来了一些令人瞩目的新特性,以提升语言的功能和开发效率。C++23也不例外,其中std::mdspan
作为一个重要的新特性,为开发者提供了一种灵活且高效的方式来处理多维数组和矩阵。本文将详细介绍std::mdspan
的相关内容,包括其定义、特点、优势、应用场景以及相关提案。
C++23简介
C++23是C++语言的最新版本,它在C++20的基础上进行了补充和优化,引入了许多新特性和改进,旨在进一步提升C++语言的功能和开发效率。与C++20相比,C++23的变化虽然没有那么显著,但依然对语言的稳固性和可用性做出了许多重要改进。C++23的新特性包括明确的对象参数(Deducing this)、if consteval
、多维下标运算符、内建衰减复制支持、标记不可达代码(std::unreachable
)、平台无关的假设([[assume]]
)、命名通用字符转义、扩展基于范围的for循环中临时变量的生命周期、constexpr
增强、简化的隐式移动、静态运算符static operator[]
以及类模板参数推导(Class Template Argument Deduction from Inherited Constructors)等。此外,C++23还对标准库进行了重要更新,增加了新的容器类型如flat_map
和flat_set
,引入了多维视图(mdspan
)以及标准生成器协程(Generator Coroutines),并改进了字符串格式化和错误处理机制(如std::expected
)。
std::mdspan的定义与特点
定义
在C++23中,std::mdspan
是一个非拥有的多维视图,用于表示连续对象序列。这个连续对象序列可以是一个简单的C数组、带有大小的指针、std::array
、std::vector
或std::string
。这种多维视图通常被称为多维数组。其定义如下:
template<class T,class Extents,class LayoutPolicy = std::layout_right,class AccessorPolicy = std::default_accessor<T>
> class mdspan;
T
:连续对象序列的类型。Extents
:指定维数及其大小;每个维度可以有静态或动态的扩展。LayoutPolicy
:指定用于访问底层内存的布局策略。AccessorPolicy
:指定如何引用底层元素。
由于C++17中的类模板参数推导(CTAD),编译器通常可以自动从初始化器的类型推导出模板参数。
特点
- 非拥有性:
std::mdspan
并不拥有它所引用的数据,它只是一个视图,这意味着它不会负责数据的生命周期管理。这使得它在处理大型数据时非常高效,因为不需要进行数据的复制。 - 多维支持:可以方便地处理多维数组,通过指定不同的维度大小和布局策略,可以灵活地表示各种多维数据结构。
- 静态和动态扩展:每个
std::mdspan
的维度可以有静态或动态的扩展。静态扩展意味着其长度在编译时指定;动态扩展意味着其长度在运行时指定。
std::mdspan的优势
零成本抽象的多维数据访问
std::mdspan
提供了零成本抽象的多维数据访问,为科学计算和图形学提供了标准方案。它允许开发者像操作多维数组一样方便地操作自定义容器,提高了代码的可读性和可维护性。例如:
#include <mdspan>
#include <vector>int main() {std::vector<double> buffer(1024);std::mdspan mat(buffer.data(), 32, 32); // 32x32矩阵视图mat[3, 4] = 2.718; // 多维下标运算符return 0;
}
减少内存开销
由于std::mdspan
是非拥有的,它不会复制数据,因此可以减少内存开销。特别是在处理大型数据集时,这一优势更加明显。
提高代码灵活性
std::mdspan
允许指定不同的布局策略和访问器策略,这使得它可以适应各种不同的数据存储方式和访问需求。例如,可以使用std::layout_left
(Fortran或MATLAB风格)来替代默认的std::layout_right
(C、C++或Python风格)。
std::mdspan的应用场景
科学计算
在科学计算中,经常需要处理多维数组和矩阵。std::mdspan
可以方便地对这些数据进行操作,提高计算效率和代码的可读性。例如,在数值模拟、机器学习等领域,多维数组的处理是非常常见的,std::mdspan
可以很好地满足这些需求。
图形学
在图形学中,图像、纹理等数据通常以多维数组的形式存储。std::mdspan
可以用于高效地访问和处理这些数据,例如进行图像滤波、纹理映射等操作。
相关提案
std::mdspan
相关的提案包括P0009R18、P2599R2、P2604R0、P2613R1、P2763R1等。这些提案对std::mdspan
的功能和实现进行了不断的完善和优化。例如,P0009R18是关于std::mdspan
的主要提案,它为std::mdspan
的引入奠定了基础;P2599R2对std::mdspan
的一些类型进行了修改;P2604R0增加了一些成员函数和类型;P2613R1添加了empty()
成员函数;P2763R1对layout_stride
的默认构造函数进行了修复。
示例代码
使用动态扩展
#include <mdspan>
#include <iostream>
#include <vector>int main() {std::vector myVec{1, 2, 3, 4, 5, 6, 7, 8};std::mdspan m{myVec.data(), 2, 4};std::cout << "m.rank(): " << m.rank() << '\n';for (std::size_t i = 0; i < m.extent(0); ++i) {for (std::size_t j = 0; j < m.extent(1); ++j) {std::cout << m[i, j] << ' ';}std::cout << '\n';}std::cout << '\n';std::mdspan m2{myVec.data(), 4, 2};std::cout << "m2.rank(): " << m2.rank() << '\n';for (std::size_t i = 0; i < m2.extent(0); ++i) {for (std::size_t j = 0; j < m2.extent(1); ++j) {std::cout << m2[i, j] << ' ';}std::cout << '\n';}return 0;
}
使用静态和动态扩展
#include <mdspan>
#include <iostream>
#include <vector>int main() {std::vector myVec{1, 2, 3, 4, 5, 6, 7, 8};std::mdspan<int, std::extents<std::size_t, 2, 4>> m{myVec.data()};std::cout << "m.rank(): " << m.rank() << '\n';for (std::size_t i = 0; i < m.extent(0); ++i) {for (std::size_t j = 0; j < m.extent(1); ++j) {std::cout << m[i, j] << ' ';}std::cout << '\n';}std::cout << '\n';std::mdspan<int, std::extents<std::size_t, std::dynamic_extent, std::dynamic_extent>> m2{myVec.data(), 4, 2};std::cout << "m2.rank(): " << m2.rank() << '\n';for (std::size_t i = 0; i < m2.extent(0); ++i) {for (std::size_t j = 0; j < m2.extent(1); ++j) {std::cout << m2[i, j] << ' ';}std::cout << '\n';}std::cout << '\n';return 0;
}
总结
std::mdspan
是C++23中一个非常实用的新特性,它为开发者提供了一种灵活、高效的方式来处理多维数组和矩阵。通过其非拥有性、多维支持、静态和动态扩展等特点,std::mdspan
在科学计算、图形学等领域有着广泛的应用前景。同时,相关的提案也在不断地完善和优化std::mdspan
的功能,使其更加强大和易用。
相关文章:
C++23 std::mdspan:多维数组处理新利器
文章目录 引言C23简介std::mdspan的定义与特点定义特点 std::mdspan的优势零成本抽象的多维数据访问减少内存开销提高代码灵活性 std::mdspan的应用场景科学计算图形学 相关提案示例代码使用动态扩展使用静态和动态扩展 总结 引言 在C的发展历程中,每一个新版本都带…...
09、底层注解-@Import导入组件
09、底层注解-Import导入组件 Import是Spring框架中的一个注解,用于将组件导入到Spring的应用上下文中。以下是Import注解的详细介绍: #### 基本用法 - **导入配置类** java Configuration public class MainConfig { // 配置内容 } Configuration Impo…...
码蹄集——N是什么、棋盘
MT1223 N是什么 给定一系列数字3、10、21、36…,输入正整数N,输出上述序列的第N个值。从N1开始计数。 格式 输入格式:输入正整数N 输出格式:输出整型 样例 1 输入:5 输出:55 备注:N小于…...
C++中聚合类(Aggregate Class)知识详解和注意事项
一、聚合类(Aggregate Class)概念 聚合(Aggregate) 是 C 中一类特殊的类类型,无用户自定义构造函数、无私有或受保护非静态数据成员、无虚函数、无基类(C11 起基类必须也是聚合且无私有/受保护成员&#x…...
python打卡day30
模块和库的导入 知识点回顾: 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致) 作业:自己新建几个不同路径文件尝试下如何导入 python的学习就像…...
PostGIS实现栅格数据导出图片标准格式【ST_AsGDALRaster】
ST_AsGDALRaster 函数应用详解:将栅格数据导出为标准图片格式 [文章目录] 一、函数概述 二、函数参数详解 三、关键功能示例 四、GDAL 选项配置指南 五、性能优化建议 六、注意事项与限制 七、应用场景 八、总结 一、函数概述 ST_AsGDALRaster是PostGIS中…...
4.6 sys模块
sys --- 仅作了解 面试之前冲击一下 python的垃圾回收机制 import sys # 1. api_version : 获取python的内部版本号 print(sys.api_version) #1013 # 2. copyright: 获取cpython的版本 print(sys.copyright) #3.getfilesystemencoding() getdefaultencoding():获…...
「HHT(希尔伯特黄变换)——ECG信号处理-第十三课」2025年5月19日
一、引言 心电信号(ECG)是反映心脏电活动的重要生理信号,其特征提取对于心脏疾病的诊断和监测具有关键意义。Hilbert - Huang Transform(HHT)作为一种强大的信号处理工具,在心电信号特征提取领域得到了广泛…...
枪机定焦系统的自动控制装置
枪机定焦系统,作为一种监控设备,通常被广泛应用于各种需要高清、远距离监控的场合。该系统的主要特点是其镜头焦距固定,不能手动或自动调节,从而确保了监控画面的稳定性和清晰度。当提到枪机定焦系统采用自动功能时,可…...
【Unity】Unity中将字典序列化
Unity中将字典序列化,在预制体上能够看到字典的内容,也可以直接在预制体上拖拽给字典赋值 直接上代码 using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine;public class SerializableD…...
VTK|箱体切割器
文章目录 效果实现类头文件实现类源文件如何调用项目git链接 效果 实现类头文件 /*** file BoxClipperController.h* brief 该头文件定义了 BoxClipperController 类,用于管理基于盒子的网格数据裁剪操作。* details 该类提供了使用 vtkBoxWidget 对网格数据进行裁…...
CS50x 01 c
1 getchar() 在 C 语言里,getchar()是一个十分常用的函数,其功能是从标准输入(一般指键盘)读取单个字符。下面为你详细介绍它的用法。 基本语法 getchar()函数的原型定义在<stdio.h>头文件中,语法形式如下&am…...
确保高质量的音视频通话,如何最大化利用视频带宽
在当今数字时代,音视频内容随处可见,对于开发者来说,理解互联网带宽变得至关重要。我们的在线体验质量,无论是观看高清电影还是演唱会直播,都严重依赖于互联网带宽的概念。在本文中,我们将揭示视频带宽的复…...
@RequestParam 和 @RequestBody、HttpServletrequest 与HttpServletResponse
在Java Web开发中,RequestParam、RequestBody、HttpServletRequest 和 HttpServletResponse 是常用的组件,它们用于处理HTTP请求和响应。下面分别介绍它们的使用场景和使用方法: 1. RequestParam RequestParam 是Spring MVC框架中的注解&am…...
HashMap 的特点及应用场景
一、HashMap 核心特点 1. 基本特性 键值对存储:基于 Map 接口实现,存储 Key-Value 对 允许 null 键/值:可以有一个 null 键和多个 null 值 非线程安全:多线程环境下需要额外的同步措施 无序存储:不保证元素的插入顺…...
day30 python 模块、包与库的高效使用指南
目录 一、Python库的分类与适用场景 表格 1.1 基础工具库 1.2 科学计算库 1.3 数据分析库 1.4 Web开发库 1.5 机器学习库 1.6 自动化脚本库 1.7 网络爬虫库 二、模块与包的导入方式 2.1 标准导入 2.2 从模块中导入特定项 2.3 非标准导入(不推荐&#x…...
JVM核心配置参数详解与调优指南
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 引言 Java虚拟机(JVM)的配置参数直接影响应用程序的性能、稳定性和资源利用率。合理配置参数能够显著提升吞吐量、降低延迟并避免内存…...
python打卡第30天
知识点回顾: 一,导入官方库的三种手段。 使用 import 直接导入整个模块 import module_name 使用 from ... import ... 导入特定功能 from module_name import function_name 使用 as 关键字重命名模块或功能 import module_name as alias # 或 from mod…...
数据要素及征信公司数据要素实践
数据要素及征信公司数据要素实践 1.数据要素的定义与核心特征2.征信公司应用数据要素的实践路径3.总结1.数据要素的定义与核心特征 数据要素是数字经济时代的新型生产要素,指以电子形式存在、通过计算方式参与生产经营活动并创造价值的数据资源。 其核心特征包括: 新型生产…...
耗时十分钟,做了一个 uniapp 灵感泡泡机
最近,我用 UniApp 搭配 CodeBuddy 实现了一个充满童话感的小应用,名叫 IdeaBubbles(灵感泡泡机)。它是一个单页 WebApp,用来记录那些转瞬即逝的灵感时刻。整个界面以梦幻气泡和彩虹玻璃拟态为主题,视觉效果…...
《Head First 设计模式》第二章 - 笔记
本书是本人写的设计模式的笔记,写下核心要点,如果你掌握过设计模式,想快速阅读本书内容,这个笔记适合你阅读。如果你是新手,有 java 基础和 oo 设计原则基础,你适合跟我一样从零阅读本书。 第一章 观察者模…...
matlab绘制光学传递函数mtf曲线
在 MATLAB 中绘制光学系统的光学传递函数(Modulation Transfer Function,MTF)曲线可以通过以下步骤实现。MTF 是描述光学系统对物体细节的传递能力的函数,通常用于分析成像系统的性能。 假设我们有一个理想的光学系统,…...
贵州某建筑物挡墙自动化监测
1. 项目简介 某建筑物位于贵州省某县城区内,靠近县城主干道,周边配套学校、医院、商贸城。建筑物临近凤凰湖、芙蓉江等水系,主打“湖景生态宜居”。改建筑物总占地面积:约5.3万平方米;总建筑面积:约15万平…...
自定义协议与序列化
前言 书接上回,我们上一篇提到了协议并且我们草率的写了一个协议,然后又对TCP的R和W留了一个伏笔,我们今天彻底做个了断。 UDP是面向数据报的,它要么不读,要么就是一次读完的,所以不存在数据断断续续的问…...
MySQL中的Change Buffer是什么,它有什么作用?
MySQL 中的 Change Buffer(更改缓冲区)是 InnoDB 存储引擎使用的一种特殊数据结构,主要用于优化对二级索引(secondary indexes)的写操作性能。 它的核心作用是: 当对表进行 INSERT、UPDATE 或 DELETE 操作…...
Ubuntu 20.04之Docker安装ES7.17.14和Kibana7.17.14
你需要已经安装如下运行环境: Ubuntu 20.04 docker 28 docker-compose 1.25 一、手动拉取镜像 docker pull docker.elastic.co/kibana/kibana:7.17.14docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.14 或者手动导入镜像 docker load -i es7.17.14.ta…...
ThreadLocal作一个缓存工具类
1、工具类 import java.util.HashMap; import java.util.Map;public class ThreadLocalUtil {// 使用Map存储多类型数据private static final ThreadLocal<Map<String, Object>> CONTEXT_HOLDER new ThreadLocal<>();// 存储数据public static void set(Str…...
DeepSeek在旅游行业的智能化革命
2025年,从贵州全域智慧旅游平台的行程规划革命,到黄山景区"AI旅行助手"的实时服务升级,再到宁夏"游宁AI"的全域智能导览,DeepSeek通过技术创新与行业场景的深度融合,正在重新定义"智慧旅游"的内涵。这场变革不仅体现在效率提升层面,更通过…...
说一下响应状态码有哪些?
HTTP响应状态码分类(RFC 7231标准) 1. 1xx(信息类) 临时响应,表示请求已被接收,需要继续处理 100 Continue:客户端应继续发送请求体 101 Switching Protocols:服务器同意升级协议(如WebSocket) 102 Processing(WebDAV):服务器正在处理但未完成 2. 2xx(成功类)…...
ABAP实战案例--获取当前数据由哪个用户锁住
1、业务场景: A用户正在打开订单,订单已上锁;B用户打开时只允许查看并提醒由哪个用户正在操作该笔订单。 2、函数使用:ENQUEUE_READ 代码示例: DATA:LV_MESSAGE TYPE SY-MSGV1,LV_UNAME TYPE UNAME.DATA:LV_GARG …...
CSS 选择器入门
一、CSS 选择器基础:快速掌握核心概念 什么是选择器? CSS 选择器就像 “网页元素的遥控器”,用于定位 HTML 中的特定元素并应用样式。 /* 结构:选择器 { 属性: 值; } */ p { color: red; } /* 选择所有<p>元素,…...
【深度学习新浪潮】如何入门人工智能?
入门人工智能(AI)需要结合数学基础、编程技能、机器学习理论和实践项目,逐步深入。以下是一个系统的学习路径,适合零基础或初学者参考: 一、打好基础:数学与编程 1. 数学基础(关键) AI的核心依赖数学,尤其是以下领域: 线性代数:向量、矩阵运算、特征分解等(用于…...
软件工程第六章-详细设计
文章目录 程序流程图PAD图N-S图(盒图)流图根据PDL创建流图把程序流程图映射到流图 程序流程图 PAD图 N-S图(盒图) 流图 根据PDL创建流图 把程序流程图映射到流图...
Profinet转Modbus TCP协议转换技术,打通能耗监控‘最后一公里’
在工业自动化领域,Profinet与Modbus TCP是两种广泛使用的通讯协议。Profinet通常用于实时性要求较高的工业控制系统,而Modbus TCP则因其简单、开放的特性广泛应用于各类设备的通信。然而,由于两者在技术规范上的差异,直接的互联互…...
C++:因子问题
【描述】 任给两个正整数N、M,求一个最小的正整数a,使得a和(M-a)都是N的因子。 【输入】 包括两个整数N、M。N不超过1,000,000。 【输出】 输出一个整数a,表示结果。如果某个案例中满足条件的正整数不存在,则在对应行输出-1 【样例…...
SAP系统的委外业务是什么?委外采购(标准委外)与工序外协的区别有哪些?
【SAP系统研究】 #SAP #委外 #外包 #代工 委外业务是很常见的业务类型。 企业生产过程中,会在自制生产之外,产生委外加工业务,也称之为外包或者代工。还有一些企业,自己只负责设计、市场等业务,而将生产加工环节交给其他公司。 一、委外产生的原因 有的企业由于环评、…...
小乌龟git中的推送账户、作者账户信息修改
文章目录 修改git文档作者信息修改git推送用户信息参考文献 修改git文档作者信息 小乌龟中的用户信息为:作者信息,并非推送用户。 上边用户信息,修改的是文件的作者信息。如果想要修改git服务中记录的推送用户信息需要修改推送用户信息。 …...
vue2.0 组件
个人简介 👨💻个人主页: 魔术师 📖学习方向: 主攻前端方向,正逐渐往全栈发展 🚴个人状态: 研发工程师,现效力于政务服务网事业 🇨🇳人生格言&…...
5月19日笔记
BGP的路由聚合 BGP(Border Gateway Protocol,边界网关协议)是互联网中用于在不同自治系统(AS)之间交换路由信息的一种协议。在BGP中,路由聚合是一种技术,它允许网络管理员通过减少路由表中冗余的…...
【SPIN】PROMELA并发编程(SPIN学习系列--3)
一、active与run:Promela的进程创建基石 在Promela语言中,**active和run**是构建并发模型的核心关键字,分别用于定义主动进程和动态创建被动进程: active proctype <进程名>() 作用:声明主动进程类型࿰…...
深入理解 Redisson 看门狗机制:保障分布式锁自动续期
在分布式系统的开发中,分布式锁是解决资源竞争、数据一致性问题的关键手段。Redisson 作为一个在 Java 领域广泛使用的 Redis 客户端框架,为我们提供了功能强大且易用的分布式锁实现。其中,看门狗(watchDog)机制更是 R…...
App 发布后才想起安全?iOS 后置混淆的实战方法与工具路线(含 Ipa Guard 应用体验)
作为一名 iOS 开发者,我们对“上线前打包”和“上线后复盘”都不会陌生。但坦白说,在忙完功能、优化、测试、提交审核这些流程之后,大多数人对“App 安全”只剩下一个念头:上线了,就算了吧。 然而,真正在 …...
k8s1.27集群部署mysql8.0双主双从
环境介绍: #节点分配 159m--->两个master,生产环境建议,一个master一个节点。 160n-->slave-0 161n-->slaves-0 #存储卷 pv-->放在节点上,没用nfs/云存储。hostpath方式存储。pv的资源分配1G,较小&#…...
C++经典库介绍
在 C 开发的漫长历程中,涌现出了许多经典的库,它们在不同的领域发挥着重要作用,极大地提升了 C 开发的效率和质量。下面为你介绍一些 C 开发中的经典库。 标准模板库(STL) STL 堪称 C 编程领域的基石,是每…...
树莓派系列教程第八弹:结合 ESP32-CAM 实现远程摄像头监控
在当今数字化时代,远程监控技术已经渗透到我们生活的方方面面。无论是家庭安防、远程办公,还是物联网设备的监控,能够随时随地查看摄像头的画面都显得尤为重要。今天,我们将带你走进一个充满创意和技术挑战的项目——利用树莓派和…...
AI人工智能写作平台:AnKo助力内容创作变革!
AI人工智能写作平台:AnKo助力内容创作变革! AI人工智能写作平台正改变内容创作方式。AnKo作为领先的AI人工智能写作平台,免费为用户提供强大创作支持。AnKo AI人工智能写作平台整合多模型技术,提升写作效率和质量。 AI人工智能写…...
学习黑客 PowerShell 详解
PowerShell 详解:管道、过滤和常用命令技术指南 🚀 作者: 海尔辛 | 发布时间: 2025-05-19 12:18:38 UTC 📋 目录 PowerShell 管道详解文本搜索与过滤结果限制与选择比较和条件操作符格式化输出对象操作与属性访问错误处理综合实例与最佳实…...
【QT】一个界面中嵌入其它界面(二)
以下是使用 QStackedWidget 实现动态切换界面的完整代码,包含详细的注释和实现步骤: 完整代码 1. 子界面类:Page1 和 Page2 首先创建两个简单的子界面类,用于嵌入到 QStackedWidget 中。 // Page1.h #ifndef PAGE1_H #define P…...
前端的面试笔记——HTMLJavaScript篇(二)前端页面性能检测
前端页面性能检测和判定是优化用户体验的核心环节,需要结合实验室数据(Lab Data)、现场数据(Field Data)和行业标准综合评估。以下是主流方法、工具及判定标准的详细解析: 一、性能检测的核心维度与指标 …...
FD+Mysql的Insert时的字段赋值乱码问题
方法一 FDQuery4.SQL.Text : INSERT INTO 信息表 (中心, 分组) values(:中心,:分组); FDQuery4.Params[0].DataType : ftWideString; //必须加这个数据类型的定义,否则会有乱码 FDQuery4.Params[1].DataType : ftWideString; //ftstring就不行,必须是…...