std:: random_access_iterator
|
定義済みヘッダ
<iterator>
|
||
|
template
<
class
I
>
concept random_access_iterator
=
|
(C++20以降) | |
random_access_iterator
の概念は、
bidirectional_iterator
を拡張し、
+=
、
+
、
-=
、
-
演算子による定数時間での前進・後退のサポート、
-
演算子による定数時間での距離計算、および添字
[]
による配列表記を追加します。
目次 |
イテレータコンセプトの決定
この概念の定義は、説明専用のエイリアステンプレート /*ITER_CONCEPT*/ によって指定されます。
/*ITER_CONCEPT*/ < I > を決定するために、 ITER_TRAITS < I > を以下のように定義する: 特殊化 std:: iterator_traits < I > がプライマリテンプレートから生成されている場合は I を、それ以外の場合は std:: iterator_traits < I > を指す:
- ITER_TRAITS < I > :: iterator_concept が有効かつ型を表す場合、 /*ITER_CONCEPT*/ < I > はその型を示す。
- そうでない場合、 ITER_TRAITS < I > :: iterator_category が有効かつ型を表す場合、 /*ITER_CONCEPT*/ < I > はその型を示す。
-
そうでない場合、
std::
iterator_traits
<
I
>
がプライマリテンプレートから生成される場合、
/*ITER_CONCEPT*/
<
I
>
は
std::random_access_iterator_tag
を示す。
(つまり、 std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: random_access_iterator_tag > が true であると仮定される。) - それ以外の場合、 /*ITER_CONCEPT*/ < I > は型を示さず、置換失敗となる。
セマンティック要件
a
と
b
を型
I
の有効なイテレータとし、
b
が
a
から到達可能であるものとする。また
n
を型
std::
iter_difference_t
<
I
>
の値で
b
-
a
に等しいものとする。
std
::
random_access_iterator
<
I
>
がモデル化されるのは、それが包含する全てのコンセプトがモデル化され、かつ以下の条件が満たされる場合に限る:
- ( a + = n ) は b と等しい。
- std:: addressof ( a + = n ) は std:: addressof ( a ) と等しい。 [1]
- ( a + n ) は ( a + = n ) と等しい。
- ( a + n ) は ( n + a ) と等しい。
-
任意の2つの正の整数
xとyについて、 a + ( x + y ) が有効ならば、 a + ( x + y ) は ( a + x ) + y と等しい。 - a + 0 は a と等しい。
- もし ( a + ( n - 1 ) ) が有効ならば、 -- b は ( a + ( n - 1 ) ) と等しい。
- ( b + = - n ) と ( b - = n ) は両方とも a と等しい。
- std:: addressof ( b - = n ) は std:: addressof ( b ) と等しい。 [1]
- ( b - n ) は ( b - = n ) と等しい。
- もし b がデリファレンス可能ならば、 a [ n ] は有効であり、かつ * b と等しい。
- bool ( a <= b ) は true である。
- すべての要求される操作は定数時間計算量を持つ。
std::addressof
はイテレータが指すオブジェクトのアドレスではなく、イテレータオブジェクト自体のアドレスを返すことに注意してください。すなわち、
operator+=
および
operator-=
は
*
this
への参照を返さなければなりません。
等価性保存
標準ライブラリコンセプトの requires expressions で宣言される式は、 equality-preserving であることが要求されます(特に明記されている場合を除く)。
暗黙的な式のバリエーション
定数左辺値オペランドに対して非変更式を使用する requires expression は、 暗黙的な式バリエーション も要求します。
注記
LegacyRandomAccessIterator
の要件とは異なり、
random_access_iterator
コンセプトは間接参照が左辺値を返すことを要求しません。
例
C++20 コンセプトを使用した std::distance の実装例を示します。
#include <iterator> namespace cxx20 { template<std::input_or_output_iterator Iter> constexpr std::iter_difference_t<Iter> distance(Iter first, Iter last) { if constexpr(std::random_access_iterator<Iter>) return last - first; else { std::iter_difference_t<Iter> result{}; for (; first != last; ++first) ++result; return result; } } } int main() { static constexpr auto il = {3, 1, 4}; static_assert(std::random_access_iterator<decltype(il.begin())> && cxx20::distance(il.begin(), il.end()) == 3 && cxx20::distance(il.end(), il.begin()) == -3); }
関連項目
|
(C++20)
|
forward_iterator
が双方向イテレータであることを指定し、後方への移動をサポートする
(コンセプト) |
|
(C++20)
|
random_access_iterator
が隣接イテレータであることを指定し、メモリ上で連続した要素を参照する
(コンセプト) |