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 是一个多维数组视图,它将多维索引映射到数组的元素。映射和元素访问策略是可配置的,底层数组不需要是连续的,甚至根本不存在于内存中。

mdspan 的每种特化 MDS 均实现 copyable,并且满足:

mdspan 的特化,若其 accessor_typemapping_typedata_handle_type 均为可平凡复制 (TriviallyCopyable) 类型,则它是可平凡复制 (TriviallyCopyable) 类型。

目录

[编辑] 模板形参

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

[编辑] 非成员函数

针对 mdspan 特化的 std::swap 算法
(函数模板) [编辑]
子视图
(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 个 int 的连续内存
    auto ms2 = std::mdspan(v.data(), 2, 6);
    // 将相同数据视作 2 x 3 x 2 的三维数组
    auto ms3 = std::mdspan(v.data(), 2, 3, 2);
 
    // 使用二维视图写入数据
    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;
 
    // 使用三维视图读回数据
    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)
连续的对象序列上的无所有权视图
(类模板) [编辑]
数值数组,数组掩码和数组切分
(类模板) [编辑]