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
的特化是 平凡可复制 (TriviallyCopyable) 类型,则其 accessor_type
、mapping_type
和 data_handle_type
都是 平凡可复制 (TriviallyCopyable) 类型。
内容 |
[编辑] 模板形参
T | - | 元素类型;既非抽象类类型亦非数组类型的完整对象类型。 |
Extents | - | 指定维度数、它们的大小以及哪些在编译时已知。必须是 std::extents 的特化。 |
LayoutPolicy | - | 指定如何将多维索引转换为底层 1D 索引(列优先 3D 数组、对称三角形 2D 矩阵等)。必须满足 布局映射策略 (LayoutMappingPolicy) 的要求。 |
AccessorPolicy | - | 指定如何将底层 1D 索引转换为 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 的维度(公有成员函数) | |
返回多维索引空间的大小 (公有成员函数) | |
检查索引空间的大小是否为零 (公有成员函数) | |
获取沿指定维度的步幅 (公有成员函数) | |
获取维度对象 (公有成员函数) | |
获取指向底层 1D 序列的指针 (公有成员函数) | |
获取映射对象 (公有成员函数) | |
获取访问器策略对象 (公有成员函数) | |
确定此 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 重载的返回类型(类模板) |
[编辑] 推导指引
[编辑] 注解
特性测试 宏 | 值 | Std | 特性 |
---|---|---|---|
__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) |
一个非拥有的、在对象的连续序列上的视图 (类模板) |
数值数组、数组掩码和数组切片 (类模板) |