命名空间
变体
操作

std::strided_slice

来自 cppreference.com
< cpp‎ | container‎ | mdspan
 
 
 
 
定义在头文件 <mdspan>
template< class OffsetType, class ExtentType, class StrideType >
struct strided_slice;
(自 C++26 起)

strided_slice 的每个特化的实例都是一个切片说明符,用于在 std::submdspan 中使用,以使用 std::mdspan 中指定维度的一组规律间隔的索引来选择元素子集。

每个 strided_slice 对象 s 的特征在于三个数据成员:偏移索引 s.offset、范围 s.extent 和步长 s.stride

假设 s.stride 大于零,由 N 表示的选择索引数由 1 + (s.extent - 1) / s.stride 确定,如果 s.extent 非零,否则为 0。将从中选择索引的半开区间由 [s.offsets.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 来指示上限值的切片规范。这是因为它可以直接为 std::mdspan 的子视图生成静态范围,如果 extentstride 都是满足 integral-constant-like 的类型的。这使得通过将编译时值与 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("] extracted from indices [");
    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] extracted from indices [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[C, D, E, F, G, H, I, J, K, L] extracted from indices [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[A, B, C, D, E] extracted from indices [0, 1, 2, 3, 4]
[C, D, E, F, G] extracted from indices [2, 3, 4, 5, 6]
[A, C, E, G, I] extracted from indices [0, 2, 4, 6, 8]
[C, F, I, L] extracted from indices [2, 5, 8, 11]
[A, F, K] extracted from indices [0, 5, 10]
[G, L, Q] extracted from indices [6, 11, 16]

[编辑] 另请参阅

valarray 的 BLAS 类切片:起始索引、长度、步长
(类) [编辑]
(C++26)
返回现有 mdspan 的子集视图
(函数模板) [编辑]