std::span
| ヘッダ <span> で定義 |
||
| template< class T, |
(C++20以降) | |
クラステンプレート span は、最初の要素がゼロの位置にある、連続したオブジェクトのシーケンスを参照できるオブジェクトを記述します。span は、シーケンス内の要素の数がコンパイル時に既知で型にエンコードされている**静的**な範囲を持つか、または**動的**な範囲を持つことができます。
span s の場合、[s.data(), s.data() + s.size()) の範囲内のポインタが無効になった場合、s の要素へのポインタ、イテレータ、および参照は無効になります。
|
|
(C++23から) |
典型的な実装では、範囲が動的な場合、T へのポインタを保持し、実装もサイズを保持します。
目次 |
[編集] テンプレートパラメータ
| T | - | 要素型; 抽象クラス型ではない完全なオブジェクト型である必要があります |
| Extent | - | シーケンス内の要素の数、動的な場合は std::dynamic_extent |
[編集] メンバ型
| メンバ型 | 定義 |
element_type
|
T
|
value_type
|
std::remove_cv_t<T> |
size_type
|
std::size_t |
difference_type
|
std::ptrdiff_t |
pointer
|
T* |
const_pointer
|
const T* |
reference
|
T& |
const_reference
|
const T& |
iterator
|
実装定義の LegacyRandomAccessIterator、ConstexprIterator、および contiguous_iterator。その value_type は value_type です。 |
const_iterator (C++23 以降) |
std::const_iterator<iterator> |
reverse_iterator
|
std::reverse_iterator<iterator> |
const_reverse_iterator (C++23 以降) |
std::const_iterator<reverse_iterator> |
注: T が const-qualified でない場合、iterator はミュータブルイテレータです。
Container のイテレータ型に対するすべての要件は、span の iterator 型にも適用されます。
[編集] メンバ定数
| 名前 | 値 |
| constexpr std::size_t extent [static] |
Extent (公開静的メンバ定数) |
[編集] メンバ関数
span を構築します(public member function) | |
span を代入します(public member function) | |
| (デストラクタ) (暗黙的に宣言) |
span を破棄します(public member function) |
イテレータ | |
| (C++23) |
先頭へのイテレータを返す (public メンバ関数) |
| (C++23) |
末尾へのイテレータを返す (public メンバ関数) |
| (C++23) |
先頭への逆イテレータを返す (public メンバ関数) |
| (C++23) |
末尾への逆イテレータを返す (public メンバ関数) |
要素アクセス | |
| 最初の要素にアクセスする (public メンバ関数) | |
| 最後の要素にアクセスする (public メンバ関数) | |
| (C++26) |
境界チェック付きで指定された要素にアクセスする (public メンバ関数) |
| 指定された要素にアクセスする (public メンバ関数) | |
| 基底となる連続ストレージに直接アクセスする (public メンバ関数) | |
監視 | |
| 要素数を返す (public メンバ関数) | |
| シーケンスのサイズをバイト単位で返します (public member function) | |
| シーケンスが空かどうかをチェックします (public member function) | |
サブビュー | |
シーケンスの最初の N 個の要素からなるサブスパンを取得します(public member function) | |
シーケンスの最後の N 個の要素からなるサブスパンを取得します(public member function) | |
| サブスパンを取得します (public member function) | |
[編集] 非メンバ関数
| (C++20) |
span をその基になるバイトのビューに変換します(関数テンプレート) |
[編集] 非メンバ定数
| (C++20) |
span が動的範囲を持つことを示す std::size_t 型の定数(定数) |
[編集] ヘルパーテンプレート
| template< class T, std::size_t Extent > constexpr bool ranges::enable_borrowed_range<std::span<T, Extent>> = true; |
(C++20以降) | |
ranges::enable_borrowed_range のこの特殊化により、span は borrowed_range を満たします。
| template< class T, std::size_t Extent > constexpr bool ranges::enable_view<std::span<T, Extent>> = true; |
(C++20以降) | |
ranges::enable_view のこの特殊化により、span は view を満たします。
[編集] 推論ガイド
[編集] 注釈
std::span の特殊化は、C++23 で正式な要件が導入される前から、既存のすべての実装ですでにトリビアルにコピー可能な型でした。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_span |
202002L |
(C++20) | std::span
|
202311L |
(C++26) | std::span::at | |
__cpp_lib_span_initializer_list |
202311L |
(C++26) | std::initializer_list から std::span を構築する |
[編集] 例
この例では、std::span を使用して、連続範囲上のいくつかのアルゴリズムを実装しています。
#include <algorithm> #include <cstddef> #include <iostream> #include <span> template<class T, std::size_t N> [[nodiscard]] constexpr auto slide(std::span<T, N> s, std::size_t offset, std::size_t width) { return s.subspan(offset, offset + width <= s.size() ? width : 0U); } template<class T, std::size_t N, std::size_t M> constexpr bool starts_with(std::span<T, N> data, std::span<T, M> prefix) { return data.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin()); } template<class T, std::size_t N, std::size_t M> constexpr bool ends_with(std::span<T, N> data, std::span<T, M> suffix) { return data.size() >= suffix.size() && std::equal(data.end() - suffix.size(), data.end(), suffix.end() - suffix.size()); } template<class T, std::size_t N, std::size_t M> constexpr bool contains(std::span<T, N> span, std::span<T, M> sub) { return std::ranges::search(span, sub).begin() != span.end(); } void println(const auto& seq) { for (const auto& elem : seq) std::cout << elem << ' '; std::cout << '\n'; } int main() { constexpr int a[]{0, 1, 2, 3, 4, 5, 6, 7, 8}; constexpr int b[]{8, 7, 6}; constexpr static std::size_t width{6}; for (std::size_t offset{}; ; ++offset) if (auto s = slide(std::span{a}, offset, width); !s.empty()) println(s); else break; static_assert("" && starts_with(std::span{a}, std::span{a, 4}) && starts_with(std::span{a + 1, 4}, std::span{a + 1, 3}) && !starts_with(std::span{a}, std::span{b}) && !starts_with(std::span{a, 8}, std::span{a + 1, 3}) && ends_with(std::span{a}, std::span{a + 6, 3}) && !ends_with(std::span{a}, std::span{a + 6, 2}) && contains(std::span{a}, std::span{a + 1, 4}) && !contains(std::span{a, 8}, std::span{a, 9}) ); }
出力
0 1 2 3 4 5 1 2 3 4 5 6 2 3 4 5 6 7 3 4 5 6 7 8
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3203 | C++20 | span の要素へのポインタ、イテレータ、および参照が無効になるタイミングが不明確であった |
明確化された |
| LWG 3903 | C++20 | span のデストラクタの宣言は不要であった |
宣言を削除 |
| P2325R3 | C++20 | ゼロでない静的範囲を持つ span は view ではなかった |
任意の span は view である |
[編集] 関連項目
| (C++23) |
多次元の所有権を持たない配列ビュー (クラステンプレート) |
| (C++20) |
イテレータと番兵のペアをviewに結合する(クラステンプレート) |
| (C++11) |
リスト初期化で作成された一時配列を参照する (クラステンプレート) |
| (C++17) |
読み取り専用の文字列ビュー (class template) |