- mdspan[meta header]
- class template[meta id-type]
- std[meta namespace]
- cpp26[meta cpp]
namespace std {
template<class OffsetType, class ExtentType, class StrideType>
struct extent_slice {
using offset_type = OffsetType;
using extent_type = ExtentType;
using stride_type = StrideType;
[[no_unique_address]] offset_type offset{};
[[no_unique_address]] extent_type extent{};
[[no_unique_address]] stride_type stride{};
};
}- no_unique_address[link /lang/cpp20/language_support_for_empty_objects.md]
extent_sliceは、多次元配列の特定次元に対してストライド幅を指定した要素取り出しを指示する集成体クラステンプレートである。
初期化時にメンバ変数名を明記する指示付き初期化をサポートし、テンプレートパラメータはテンプレート引数推論の利用を想定した設計となっている。
offset: 元の多次元配列における取り出し開始位置extent: 取り出す要素数(取り出した多次元配列ビューの、その次元の要素数)stride: 要素取り出しストライド幅
取り出される要素のインデックスはoffset, offset + stride, ..., offset + (extent - 1) * strideとなる。
// 開始位置=1, 要素数=4, ストライド幅=3
// → インデックス 1, 4, 7, 10 の要素を取り出す
std::extent_slice{.offset=1, .extent=4, .stride=3}取り出す要素数ではなく、取り出し元の半開区間で指定したい場合はrange_sliceを使用する。
OffsetType, ExtentType, StrideTypeは符号付き整数型または符号無し整数型、もしくはintegral-constant-likeのモデルであること。
| 名前 | 説明 | 対応バージョン |
|---|---|---|
offset_type |
offsetの型 |
C++26 |
extent_type |
extentの型 |
C++26 |
stride_type |
strideの型 |
C++26 |
extentをconstant_wrapperで静的に指定すると、strideが実行時の値であっても、取り出した多次元配列ビューの要素数は静的となる
#include <mdspan>
#include <print>
#include <numeric>
int main()
{
// 12要素の1次元配列ビュー
int arr[12];
std::ranges::iota(arr, 0);
std::mdspan vec0{arr};
// 開始位置1から、ストライド幅3で4要素を取り出す
auto vec1 = std::submdspan(vec0, std::extent_slice{1, 4, 3});
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
// ^ . . ^ . . ^ . . ^
std::println("vec1:");
for (size_t i = 0; i < vec1.extent(0); i++) {
std::print(" {}", vec1[i]);
}
// 開始位置0から、ストライド幅4で3要素を取り出す(指示付き初期化を利用)
auto vec2 = std::submdspan(vec0,
std::extent_slice{.offset=0, .extent=3, .stride=4});
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
// ^ . . . ^ . . . ^ . . .
std::println("\nvec2:");
for (size_t i = 0; i < vec2.extent(0); i++) {
std::print(" {}", vec2[i]);
}
}- std::extent_slice[color ff0000]
- std::submdspan[link submdspan.md]
- std::print[link /reference/print/print.md]
- std::ranges::iota[link /reference/numeric/ranges_iota.md]
vec1:
1 4 7 10
vec2:
0 4 8
- C++26
- Clang: ??
- GCC: 17 [mark verified]
- ICC: ??
- Visual C++: ??
- P2630R4 Submdspan
- P3982R2 Split
strided_sliceintoextent_sliceandrange_slicefor C++26- C++26のリリース前に、このクラスは
strided_sliceからextent_sliceへ改名され、extentメンバ変数の意味が「取り出し元の要素数」から「取り出す要素数」へ変更された。取り出す要素数を除算なしで直接指定でき、strideが実行時の値でも要素数を静的に指定できるようにするためである
- C++26のリリース前に、このクラスは