std::mdspan

来自cppreference.com
< cpp‎ | container
在标头 <mdspan> 定义
template<

    class T,
    class Extents,
    class LayoutPolicy = std::layout_right,
    class AccessorPolicy = std::default_accessor<T>

> class mdspan;
(C++23 起)

std::mdspan 是一个提供对象的相接序列的非拥有视图,它将其重新解释为多维数组。

模板形参

T - 元素类型;既不是抽象类也不是数组类型的完整对象类型
Extents - 指定维度的数量、大小以及编译时已知的维度。必须是 std::extents 的特化
LayoutPolicy - 指定如何将多维索引转换为基础一维索引(列优先三维数组、对称三角二维矩阵等)
AccessorPolicy - 指定如何将基础一维索引转换为对 T 的引用

成员类型

成员类型 定义
extents_type Extents
layout_type LayoutPolicy
accessor_type AccessorPolicy
mapping_type LayoutPolicy::mapping<Extents>
element_type T
value_type std::remove_cv_t<T>
index_type Extents::index_type
size_type Extents::size_type
rank_type Extents::rank_type
data_handle_type AccessorPolicy::data_handle_type
reference AccessorPolicy::reference

成员函数

构造一个 mdspan
(公开成员函数)
给一个 mdspan 赋值
(公开成员函数)
元素访问
访问指定多维索引处的元素
(公开成员函数)
观察器
返回多维索引空间的大小
(公开成员函数)
检查索引所占空间大小是否为零
(公开成员函数)
获取沿指定维度的步长
(公开成员函数)
获取范围(extent)对象
(公开成员函数)
获取指向基础一维序列的指针
(公开成员函数)
获取映射(mapping)对象
(公开成员函数)
获取访问器策略对象
(公开成员函数)
确定此 mdspan 的映射是否唯一(每个索引组合映射到不同的基础元素)
(公开成员函数)
确定此 mdspan 的映射是否详尽(exhaustive)(可以使用某些索引组合访问每个底层元素)
(公开成员函数)
确定此 mdspan 的映射是否跨步(在每个维度中,每次递增索引都会跳过相同数量的基础元素)
(公开成员函数)
确定此 mdspan 的布局映射是否始终唯一(unique)
(公开成员函数)
确定此 mdspan 的布局映射(layout mapping)是否总是详尽的
(公开成员函数)
确定此 mdspan 的布局映射是否始终跨步(strided)
(公开成员函数)

非成员函数

专门用于 mdspan 的 std::swap 算法
(函数模板)

辅助类型和模板

(C++23)
某秩多维索引空间的一个描述符
(类模板)
(C++23)
所有动态 std::extents 的方便别名
(类模板)
行优先多维数组布局映射;最右边的范围具有步幅 1
(类)
列优先多维数组布局映射;最左边的范围具有步幅 1
(类)
具有用户自定义步长的布局映射
(类)

指导指引

注解

功能特性测试 标准 备注
__cpp_lib_mdspan 202207L (C++23) std::mdspan

示例

可以在 https://godbolt.org/z/PK7bccGr3 中预览

#include <vector>
#include <mdspan>
#include <print>
 
int main()
{
  std::vector v = {1,2,3,4,5,6,7,8,9,10,11,12};
 
  // View data as contiguous memory representing 2 rows of 6 ints each
  auto ms2 = std::mdspan(v.data(), 2, 6);
  // View the same data as a 3D array 2 x 3 x 2
  auto ms3 = std::mdspan(v.data(), 2, 3, 2);
 
  // write data using 2D view
  for(size_t i=0; i != ms2.extent(0); i++)
    for(size_t j=0; j != ms2.extent(1); j++)
      ms2[i, j] = i*1000 + j;
 
  // read back using 3D view
  for(size_t i=0; i != ms3.extent(0); i++)
  {
    std::println("slice @ i = {}", i);
    for(size_t j=0; j != ms3.extent(1); j++)
    {
      for(size_t k=0; k != ms3.extent(2); k++)
        std::print("{} ",  ms3[i, j, k]);
      std::println("");
    }
  }
}

输出:

slice @ i = 0
0 1
2 3
4 5
slice @ i = 1
1000 1001
1002 1003
1004 1005

参阅

(C++20)
对象的连续序列上的无所有权视图
(类模板)
数值数组,数组掩码和数组切分
(类模板)