Namespaces
Variants

std:: strided_slice

From cppreference.net
定义于头文件 <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 大于零,当 s. extent 非零时,所选索引的数量记作 N ,其计算公式为 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("] 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(