std::strided_slice
Определён в заголовочном файле <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.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. Это позволяет напрямую задавать статический размер для подвидa std::mdspan, если и extent, и stride имеют типы, удовлетворяющие концепту 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 (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/mdspan/strided_slice