Namespaces
Variants

std:: mdspan

From cppreference.net
定义于头文件 <mdspan>
template <

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

> class mdspan ;
(C++23 起)

std::mdspan 是一种多维数组视图,可将多维索引映射到数组的元素。其映射和元素访问策略可配置,且底层数组不必是连续的,甚至无需实际存在于内存中。

每个 MDS mdspan 特化都建模 copyable 概念并满足:

mdspan accessor_type mapping_type data_handle_type 均为 可平凡复制 类型时,该 mdspan 特化本身也是 可平凡复制 类型。

目录

模板参数

T - 元素类型;必须是完整对象类型,既不能是抽象类类型也不能是数组类型。
Extents - 指定维度数量、各维度大小以及哪些维度在编译时已知。必须是 std::extents 的特化。
LayoutPolicy - 指定如何将多维索引转换为底层一维索引(列优先三维数组、对称三角二维矩阵等)。必须满足 LayoutMappingPolicy 的要求。
AccessorPolicy - 指定如何将底层一维索引转换为 T 的引用。必须满足约束条件 std:: is_same_v < T, typename AccessorPolicy​ :: ​element_type > true 。必须满足 AccessorPolicy 的要求。

成员类型

成员类型 定义
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

数据成员

成员 描述
accessor_type acc_ (私有) 访问器
( 仅用于说明的成员对象* )
mapping_type map_ (私有) 布局映射
( 仅用于说明的成员对象* )
data_handle_type ptr_ (私有) 底层数据句柄
( 仅用于说明的成员对象* )

成员函数

构造一个 mdspan
(公开成员函数)
赋值一个 mdspan
(公开成员函数)
元素访问
访问指定多维索引处的元素
(公开成员函数)
观察器
[static]
返回 mdspan 的秩
(公开静态成员函数)
返回 mdspan 的动态秩
(公开静态成员函数)
返回 mdspan 在给定秩索引处的静态范围大小
(公开静态成员函数)
返回 mdspan 在给定秩索引处的范围
(公开成员函数)
返回多维索引空间的大小
(公开成员函数)
检查索引空间的大小是否为零
(公开成员函数)
获取指定维度上的步幅
(公开成员函数)
获取范围对象
(公开成员函数)
获取指向底层一维序列的指针
(公开成员函数)
获取映射对象
(公开成员函数)
获取访问器策略对象
(公开成员函数)
确定此 mdspan 的映射是否唯一(每个索引组合都映射到不同的底层元素)
(公开成员函数)
确定此 mdspan 的映射是否穷举(每个底层元素都可以通过某些索引组合访问)
(公开成员函数)
确定此 mdspan 的映射是否跨步(在每个维度中,递增索引每次跳过相同数量的底层元素)
(公开成员函数)
确定此 mdspan 的布局映射是否始终唯一
(公开静态成员函数)
确定此 mdspan 的布局映射是否始终穷举
(公开静态成员函数)
确定此 mdspan 的布局映射是否始终跨步
(公开静态成员函数)

非成员函数

特化 std::swap 算法以用于 mdspan
(函数模板)
子视图
(C++26)
返回现有 mdspan 的子集视图
(函数模板)
根据现有 extents 和切片说明符创建新的 extents
(函数模板)

辅助类型与模板

(C++23)
描述某个秩的多维索引空间的描述符
(类模板)
(C++23) (C++26)
全动态 std::extents 的便捷别名模板
(别名模板)
用于索引访问 mdspan 元素的类型
(类模板)
用于对齐访问 mdspan 元素的类型
(类模板)
布局映射策略
列主序多维数组布局映射策略;最左侧维度步长为 1
(类)
行主序多维数组布局映射策略;最右侧维度步长为 1
(类)
具有用户自定义步长的布局映射策略
(类)
列主序布局映射策略,其填充步长可大于或等于最左侧维度
(类模板)
行主序布局映射策略,其填充步长可大于或等于最右侧维度
(类模板)
子视图辅助工具
描述指定维度中完整索引范围的切片说明符标签
(标签)
表示由偏移量、维度和步长指示的规则间隔索引集的切片说明符
(类模板)
submdspan_mapping 重载的返回类型
(类模板)

推导指引

注释

特性测试 标准 特性
__cpp_lib_mdspan 202207L (C++23) std::mdspan
__cpp_lib_submdspan 202306L (C++26) std::submdspan
202403L (C++26) std::mdspan 填充布局
__cpp_lib_aligned_accessor 202411L (C++26) std::aligned_accessor

示例

可在 Compiler Explorer 上预览。

#include <cstddef>
#include <mdspan>
#include <print>
#include <vector>
int main()
{
    std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    // 将数据视为连续内存,表示 2 行,每行 6 个整数
    auto ms2 = std::mdspan(v.data(), 2, 6);
    // 将相同数据视为 3D 数组 2 x 3 x 2
    auto ms3 = std::mdspan(v.data(), 2, 3, 2);
    // 使用 2D 视图写入数据
    for (std::size_t i = 0; i != ms2.extent(0); i++)
        for (std::size_t j = 0; j != ms2.extent(1); j++)
            ms2[i, j] = i * 1000 + j;
    // 使用 3D 视图读取数据
    for (std::size_t i = 0; i != ms3.extent(0); i++)
    {
        std::println("slice @ i = {}", i);
        for (std::size_t j = 0; j != ms3.extent(1); j++)
        {
            for (std::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)
连续对象序列的非拥有视图
(类模板)
数值数组、数组掩码和数组切片
(类模板)