span[meta header]
std[meta namespace]
class template[meta id-type]
cpp20[meta cpp]
namespace std {
template <class ElementType , size_t Extent = dynamic_extent>
class span ;
// viewコンセプトを有効化する
template <class ElementType , size_t Extent>
inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true ;
// borrowed_rangeコンセプトを有効化する
template <class ElementType , size_t Extent>
inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true ;
}
size_t[link /reference/cstddef/size_t.md]
dynamic_extent[link dynamic_extent.md]
enable_view[link /reference/ranges/enable_view.md]
enable_borrowed_range[link /reference/ranges/enable_borrowed_range.md]
std::span
は、シーケンスの所有権を保持せず、部分シーケンスを参照するクラスである。
このクラスは、std::vector
や配列といったコンテナから一部の連続的な要素を抽出し、それらの要素にのみなんらかの処理を適用する、という目的に使用できる。
文字列操作に特化したクラスとしてstd::basic_string_view
が定義されているが、こちらはメモリ連続性をもつあらゆるコンテナに適用できる。
このクラスは、トリビアルコピー可能 である(C++23)
このクラスの対象は、メモリの連続性を持つシーケンスである。例として、以下は対象のシーケンスである:
メモリ連続性をもつクラスは、非メンバ関数data()
によってポインタを取得でき、非メンバ関数size()
によって要素数を取得できること。それらの関数は、ADLによって呼び出される。
std::span
は、静的な要素数をもつ場合と、動的な要素数をもつ場合の両方をサポートする。それはテンプレートパラメータExtent
によって表される。動的な要素数をもつ場合は、Extent
としてstd::dynamic_extent
を指定する。動的な要素数は、std::vector
を参照したり、ポインタと要素数の組を扱ったり、参照範囲を動的に変更したりする場合に必要となる。
静的な要素数をもつ場合、メンバ定数extent
に要素数が保持されるため、メンバ変数として要素数を保持する必要がなく、領域を節約する最適化を行える。
ElementType
は、抽象型ではない完全オブジェクト型であること
std::span
が参照する範囲[s.
data()
, s.
data()
+ s.
size()
)
に含まれるポインタを無効にする操作を行った場合、std::span
オブジェクトのメンバ関数から返されるその範囲のポインタ、イテレータ、*this
以外の参照が無効になる
名前
説明
対応バージョン
(constructor)
コンストラクタ
C++20
~span() = default;
デストラクタ
C++20
span& operator=(const span&) = default;
span& operator=(span&&) = default;
代入演算子
C++20
名前
説明
対応バージョン
first
先頭N個の要素を参照するspan
オブジェクトを取得する
C++20
last
末尾N個の要素を参照するspan
オブジェクトを取得する
C++20
subspan
任意の位置からN個の要素を参照するspan
オブジェクトを取得する
C++20
名前
説明
対応バージョン
size
参照している要素数を取得する
C++20
size_bytes
参照している範囲のバイト数を取得する
C++20
empty
参照している範囲が空かどうかを判定する
C++20
名前
説明
対応バージョン
operator[]
参照範囲から、任意の位置の要素を取得する
C++20
at
参照範囲から、任意の位置の要素を取得する
C++26
front
参照範囲の先頭要素を取得する
C++20
back
参照範囲の末尾要素を取得する
C++20
data
参照範囲の先頭を指すポインタを取得する
C++20
名前
説明
対応バージョン
begin
先頭要素を指すイテレータを取得する
C++20
end
末尾要素の次を指すイテレータを取得する
C++20
rbegin
末尾要素を指す逆順イテレータを取得する
C++20
rend
先頭要素の前を指す逆順イテレータを取得する
C++20
cbegin
先頭の要素を指す読み取り専用イテレータを取得する
C++23
cend
末尾の次を指す読み取り専用イテレータを取得する
C++23
crbegin
末尾を指す読み取り専用逆イテレータを取得する
C++23
crend
先頭の前を指す読み取り専用逆イテレータを取得する
C++23
名前
説明
対応バージョン
static constexpr size_type extent = Extent;
要素数。値が-1
であれば動的な要素数、そうでなければ静的な固定要素数
C++20
名前
説明
対応バージョン
element_type
要素型 ElementType
C++20
value_type
CV修飾を除いた要素型 remove_cv_t
<ElementType>
C++20
size_type
インデックスを表す符号なし整数型 size_t
C++20
difference_type
イテレータの差を表す符号付き整数型 ptrdiff_t
C++20
pointer
ポインタ型 element_type*
C++20
const_pointer
const
ポインタ型 const element_type*
C++20
reference
参照型 element_type&
C++20
const_reference
const
参照型 const element_type&
C++20
iterator
実装定義のイテレータ型。contiguous_iterator
、random_access_iterator
、constexprイテレータのモデルであり、コンテナのイテレータに対するすべての要件を満たす
C++20
reverse_iterator
逆順イテレータ reverse_iterator
<iterator>
C++20
const_iterator
読み取り専用イテレータ std::const_iterator
<iterator>
C++23
const_reverse_iterator
読み取り専用逆イテレータ std::const_iterator
<reverse_iterator>
C++23
#include < iostream>
#include < span>
#include < vector>
#include < utility>
// メモリ連続性をもつあらゆる範囲を出力する関数。
// std::spanオブジェクトはコピーで受け取るのが基本的な使い方
template <class T , std::size_t Extent>
void print (std::span<T, Extent> s)
{
const char * delimiter = " " ;
std::cout << ' {' ;
for (const T& x : s) {
std::cout << std::exchange (delimiter, " ," ) << x;
}
std::cout << ' }' << std::endl;
}
int main ()
{
std::vector<int > v = {1 , 2 , 3 , 4 , 5 };
int ar[] = {1 , 2 , 3 , 4 , 5 };
// spanに変換してコンテナ全体を出力
print (std::span{v});
// コンテナの一部の要素を出力
print (std::span{v}.subspan (1 , 3 ));
// ポインタと要素数を指定した範囲を参照して、
// 範囲for文を使用する
print (std::span<int >{ar, 3 });
}
std::exchange[link /reference/utility/exchange.md]
subspan[link span/subspan.md]
{1,2,3,4,5}
{2,3,4}
{1,2,3}
データのヘッダ情報とボディ情報をコピーなしで分割する
#include < iostream>
#include < span>
#include < vector>
#include < utility>
template <class T >
void process_header (std::span<T> s)
{
const char * delimiter = " " ;
std::cout << " [header] : " ;
for (int x : s) {
std::cout << std::exchange (delimiter, " ," ) << x;
}
std::cout << std::endl;
}
template <class T >
void process_body (std::span<T> s)
{
const char * delimiter = " " ;
std::cout << " [body] : " ;
for (int x : s) {
std::cout << std::exchange (delimiter, " ," ) << x;
}
std::cout << std::endl;
}
template <class T >
void f (std::span<T> s)
{
std::size_t header_size = 3 ;
process_header (s.first (header_size));
process_body (s.last (s.size () - header_size));
}
int main ()
{
std::vector<int > data = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };
f (std::span{data});
}
s.first[link span/first.md]
s.last[link span/last.md]
s.size()[link span/size.md]
std::exchange[link /reference/utility/exchange.md]
[header] : 1,2,3
[body] : 4,5,6,7,8,9,10
Clang : 9.0 [mark verified]
GCC : 10.1 [mark verified]
Visual C++ : 2019 Update 6 [mark verified]