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

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_mapflat_set,引入了多维视图(mdspan)以及标准生成器协程(Generator Coroutines),并改进了字符串格式化和错误处理机制(如std::expected)。

std::mdspan的定义与特点

定义

在C++23中,std::mdspan是一个非拥有的多维视图,用于表示连续对象序列。这个连续对象序列可以是一个简单的C数组、带有大小的指针、std::arraystd::vectorstd::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),编译器通常可以自动从初始化器的类型推导出模板参数。

特点

  1. 非拥有性std::mdspan并不拥有它所引用的数据,它只是一个视图,这意味着它不会负责数据的生命周期管理。这使得它在处理大型数据时非常高效,因为不需要进行数据的复制。
  2. 多维支持:可以方便地处理多维数组,通过指定不同的维度大小和布局策略,可以灵活地表示各种多维数据结构。
  3. 静态和动态扩展:每个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的功能,使其更加强大和易用。

http://www.xdnf.cn/news/7174.html

相关文章:

  • 如何用Python批量解压ZIP文件?快速解决方案
  • NC105NC106美光固态颗粒NC108NC109
  • Python学习笔记--使用Django操作mysql
  • C++开源库argh使用教程
  • 20250519使用TF卡将NanoPi NEO core开发板刷机为Ubuntu core22.04.3系统完成之后执行poweroff自动关机
  • CSS之网页元素的显示与隐藏(旧土豆网遮罩案例)
  • Unity开发:预制体、接口与枚举
  • 光子神经网络加速器编程范式研究:光子矩阵乘法的误差传播模型构建
  • 从单体到分布式:深入解析Data Mesh架构及其应用场景与价值
  • 【VMware】虚拟机运行 Linux Ubuntu、MAC 安装和配置
  • 整合安全能力:观测云进一步强化数据价值
  • 如何利用DeepSeek提升工作效率
  • 估分啦~全国青少年信息素养大赛部分赛项已考完~图形化/算法创意实践
  • PWM讲解+STM32任意频率、占空比、脉宽生成函数介绍
  • 2023年河南CCPC(ABCEFHK)
  • 算法第21天 | 第77题. 组合、216. 组合总和 III、17. 电话号码的字母组合
  • 探索 Python 的利器:help()、dir() 与 AI 工具的结合应用
  • Linux `touch` 命令深度解析与高阶应用指南
  • LangGraph深度解析:构建持久化、可观测的智能体工作流
  • Addressable-动态加载单个资源
  • DeepSeek 赋能基因编辑:从理论模型到临床实践的 AI 跃迁
  • 二:操作系统之进程控制块(PCB)
  • Redis实现分布式锁的进阶版:Redisson实战指南
  • Qt如何设置图标
  • Python3中的re.findall()和re.search()的区别是什么?
  • python学习day29
  • C++11关键字thread_local
  • 001 嵌入式软件开发工程师实习篇面试——首战总结
  • 使用 Auto-Keras 进行自动化机器学习
  • ElasticSearch-集群