std::mdspan
来自 cppreference.cn
定义于头文件 <mdspan> |
||
template< class T, |
(C++23 起) | |
std::mdspan
是一个多维数组视图,它将多维索引映射到数组的某个元素。映射和元素访问策略是可配置的,并且底层数组不要求连续,甚至根本不需要存在于内存中。
mdspan
的每个特化 MDS
都建模 copyable
且满足
- std::is_nothrow_move_constructible_v<MDS> 为 true,
- std::is_nothrow_move_assignable_v<MDS> 为 true,且
- std::is_nothrow_swappable_v<MDS> 为 true。
如果 mdspan
的特化的 accessor_type
、mapping_type
和 data_handle_type
是 TriviallyCopyable 类型,那么它也是 TriviallyCopyable 类型。
目录 |
[编辑] 模板形参
T | - | - 元素类型;一个既非抽象类类型也非数组类型的完整对象类型。 |
Extents | - | - 指定维数、它们的大小以及哪些维数在编译时已知。必须是 std::extents 的一个特化。 |
LayoutPolicy | - | - 指定如何将多维索引转换为底层的一维索引(例如列主序的3D数组、对称的三角2D矩阵等)。必须满足 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 (公开成员函数) | |
元素访问 | |
访问指定多维索引处的元素 (公开成员函数) | |
观察器 | |
[静态] |
返回 mdspan 的秩(公开静态成员函数) |
[静态] |
返回 mdspan 的动态秩(公开静态成员函数) |
[静态] |
返回 mdspan 在给定秩索引处的静态区段大小(公开静态成员函数) |
返回 mdspan 在给定秩索引处的区段大小(公开成员函数) | |
返回多维索引空间的大小 (公开成员函数) | |
检查索引空间的大小是否为零 (公开成员函数) | |
获取沿指定维度的步长 (公开成员函数) | |
获取区段对象 (公开成员函数) | |
获取指向底层一维序列的指针 (公开成员函数) | |
获取映射对象 (公开成员函数) | |
获取访问器策略对象 (公开成员函数) | |
判断此 mdspan 的映射是否唯一(即每个索引组合都映射到不同的底层元素) (公开成员函数) | |
判断此 mdspan 的映射是否穷尽(即每个底层元素都可以通过某个索引组合访问到) (公开成员函数) | |
判断此 mdspan 的映射是否是跨步的(即在每个维度中,增加索引都会跳过相同数量的底层元素) (公开成员函数) | |
[静态] |
判断此 mdspan 的布局映射是否总是唯一的 (公开静态成员函数) |
判断此 mdspan 的布局映射是否总是穷尽的 (公开静态成员函数) | |
判断此 mdspan 的布局映射是否总是跨步的 (公开静态成员函数) |
[编辑] 非成员函数
(C++23) |
为 mdspan 特化 std::swap 算法 (函数模板) |
子视图 | |
(C++26) |
返回一个现有 mdspan 的子集视图(函数模板) |
(C++26) |
从现有的区段和切片说明符创建新的区段 (函数模板) |
[编辑] 辅助类型和模板
(C++23) |
某个秩的多维索引空间的描述符 (类模板) |
(C++23)(C++26) |
全动态 std::extents 的便捷别名模板 (别名模板) |
(C++23) |
用于对 mdspan 元素进行索引访问的类型(类模板) |
(C++26) |
用于对 mdspan 元素进行对齐访问的类型(类模板) |
布局映射策略 | |
(C++23) |
列主序多维数组布局映射策略;最左侧区段的步长为 1 (类) |
(C++23) |
行主序多维数组布局映射策略;最右侧区段的步长为 1 (类) |
(C++23) |
具有用户定义步长的布局映射策略 (类) |
(C++26) |
列主序布局映射策略,其填充步长可以大于或等于最左侧的区段 (类模板) |
(C++26) |
行主序布局映射策略,其填充步长可以大于或等于最右侧的区段 (类模板) |
子视图辅助项 | |
(C++26) |
一个切片说明符标签,描述指定区段中索引的完整范围。 (标签) |
(C++26) |
一个切片说明符,表示由偏移量、区段和步长指示的一组等距索引 (类模板) |
(C++26) |
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}; // 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 (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; // Read back using 3D view 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) |
一个连续对象序列的非拥有视图 (类模板) |
数值数组、数组掩码和数组切片 (类模板) |