std::strided_slice
| 在标头 <mdspan> 定义
|
||
| |
(C++26 起) | |
strided_slice 的每个特化的实例都是 std::submdspan 中使用的切片说明符,它使用在 std::mdspan 的某个指定维度上有规律排布的索引集合选择一个元素子集。
每个 strided_slice 对象 s 都以三个数据成员来描绘:偏移量索引 s.offset、尺度 s.extent 和步长 s.stride。
给定大于零的 s.stride,由 N 代表所选中索引的数量,若 s.extent 非零则确定为 1 + (s.extent - 1) / s.stride,否则为 0。索引从半开区间 [s.offset, s.offset + s.extent) 中选取。所选中索引的序列为:s.offset, ..., s.offset + (N - 1) * s.stride。
这个类模板没有基类或声明除了下述之外的成员。
模板形参
| OffsetType | - | 偏移量的类型 |
| ExtentType | - | 尺度的类型 |
| StrideType | - | 步长的类型 |
| 类型要求 | ||
| -所有模板形参都必须是无符号或有符号整数类型或者满足 integral-constant-like | ||
如果不满足类型要求则程序非良构
成员类型
| 成员类型 | 定义 |
offset_type
|
OffsetType
|
extent_type
|
ExtentType
|
stride_type
|
StrideType
|
数据成员
| 成员名字 | 定义 |
offset |
offset_type 类型的起始索引 (公开成员对象) |
extent |
extent_type 类型的值,加到偏移量上以定义索引上界 (公开成员对象) |
stride |
stride_type 类型的增加值,等价于两个索引之间的距离 (公开成员对象) |
所有这些成员都被声明为带有 [[no_unique_address]] 属性,并具有默认成员初始化式以使各个成员被值初始化。
注解
strided_slice 的每个特化都是聚合体类,允许数据成员的聚合初始化(包括指派初始化,例如,std::strided_slice{.offset = 2, .extent = 10, .stride = 3})。
strided_slice 的切片说明利用了数据成员 extent 的优势,这点与其他使用 end 来指示上界值的切片说明有所不同。这是因为在 extent 和 stride 都是满足 integral-constant-like 的类型时,它可以为 std::mdspan 的子视图直接生成静态尺度。这样就允许通过混用编译时值和运行时的 offset 值来高效提取具有静态尺度的子视图。
示例
#include <mdspan>
#include <print>
template <typename View, typename O = int, typename E = int, typename S = int>
requires (View::extents_type::rank() == 1)
void print_sliced_view(View v, std::strided_slice<O, E, S> s)
{
using index_type = View::index_type;
auto subview = std::submdspan(v, s);
const auto& submap = subview.mapping();
std::print("[");
bool uses_comma = false;
for (index_type i = 0; i != subview.extent(0); ++i)
{
if (uses_comma)
std::print(", ");
std::print("{}", subview[i]);
uses_comma = true;
}
uses_comma = false;
std::print("] 提取于索引 [");
for (index_type i = 0; i != subview.extent(0); ++i)
{
if (uses_comma)
std::print(", ");
std::print("{}", submap(i) + s.offset);
uses_comma = true;
}
std::println("]");
}
int main()
{
static constexpr char letters[]
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
};
constexpr std::mdspan md(letters, 26);
print_sliced_view(md, {.offset = 0, .extent = 10, .stride = 1});
print_sliced_view(md, {.offset = 2, .extent = 10, .stride = 1});
print_sliced_view(md, {.offset = 0, .extent = 5, .stride = 1});
print_sliced_view(md, {.offset = 2, .extent = 5, .stride = 1});
print_sliced_view(md, {.offset = 0, .extent = 10, .stride = 2});
print_sliced_view(md, {.offset = 2, .extent = 10, .stride = 3});
print_sliced_view(md, {.offset = 0, .extent = 15, .stride = 5});
print_sliced_view(md, {.offset = 6, .extent = 15, .stride = 5});
}
输出:
[A, B, C, D, E, F, G, H, I, J] 提取于索引 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[C, D, E, F, G, H, I, J, K, L] 提取于索引 [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[A, B, C, D, E] 提取于索引 [0, 1, 2, 3, 4]
[C, D, E, F, G] 提取于索引 [2, 3, 4, 5, 6]
[A, C, E, G, I] 提取于索引 [0, 2, 4, 6, 8]
[C, F, I, L] 提取于索引 [2, 5, 8, 11]
[A, F, K] 提取于索引 [0, 5, 10]
[G, L, Q] 提取于索引 [6, 11, 16]
参阅
| valarray 的 BLAS 式切片:起始下标、长度、跨度 (类) | |
(C++26) |
返回现存 mdspan 的子集上的视图 (函数模板) |