namespace std {
template<class I>
concept random_access_iterator =
bidirectional_iterator<I> &&
derived_from<ITER_CONCEPT(I), random_access_iterator_tag> &&
totally_ordered<I> &&
sized_sentinel_for<I, I> &&
requires(I i, const I j, const iter_difference_t<I> n) {
{ i += n } -> same_as<I&>;
{ j + n } -> same_as<I>;
{ n + j } -> same_as<I>;
{ i -= n } -> same_as<I&>;
{ j - n } -> same_as<I>;
{ j[n] } -> same_as<iter_reference_t<I>>;
};
}
概要
random_access_iterator
は、イテレータ型I
がランダムアクセスイテレータであることを表すコンセプトである。
random_access_iterator
となるイテレータは、双方向イテレータであり、+= + -= -
による定数時間での進行と、-
による定数時間での距離の計算が可能である。
モデル
iter_difference_t<I>
の示す型D
、D
の値n
、型I
の有効なイテレータa
と++a
をn
回適用したイテレータb
について次の条件を満たす場合に限って、型I
はrandom_access_iterator
のモデルである。
(a += n)
はb
と等値(equal)addressof(a += n)
はaddressof(a)
と等値+=
は*this
を返す
(a + n)
は(a += n)
と等値D
の2つの正の値x, y
について(a + D(x + y))
が有効ならば、(a + D(x + y))
は((a + x) + y)
と等値- 結合則
(a + D(0))
はa
と等値(a + D(n - 1))
が有効ならば、(a + n)
は[](I c){ return ++c; }(a + D(n - 1))
と等値(b += D(-n))
はa
と等値(b -= n)
はa
と等値addressof(b -= n)
はaddressof(b)
と等値-=
は*this
を返す
(b - n)
は(b -= n)
と等値b
が間接参照可能ならば、a[n]
は有効であり*b
と等値bool(a <= b) == true
例
#include <iostream>
#include <concepts>
#include <iterator>
#include <vector>
#include <forward_list>
#include <list>
template<std::random_access_iterator I>
void f(const char* name) {
std::cout << name << " is random_access_iterator" << std::endl;
}
template<typename I>
void f(const char* name) {
std::cout << name << " is not random_access_iterator" << std::endl;
}
struct sample_random_access_iterator {
friend auto operator++(sample_random_access_iterator&) -> sample_random_access_iterator&;
friend auto operator++(sample_random_access_iterator&, int) -> sample_random_access_iterator;
friend auto operator--(sample_random_access_iterator&) -> sample_random_access_iterator&;
friend auto operator--(sample_random_access_iterator&, int) -> sample_random_access_iterator;
friend auto operator+(const sample_random_access_iterator&, int) -> sample_random_access_iterator;
friend auto operator+(int, const sample_random_access_iterator&) -> sample_random_access_iterator;
friend auto operator+=(sample_random_access_iterator&, int) -> sample_random_access_iterator&;
friend auto operator-(const sample_random_access_iterator&, int) -> sample_random_access_iterator;
friend auto operator-=(sample_random_access_iterator&, int) -> sample_random_access_iterator&;
friend auto operator-(const sample_random_access_iterator&, const sample_random_access_iterator&) -> int;
friend auto operator*(const sample_random_access_iterator&) -> int&;
auto operator[](int) const -> int&;
friend std::strong_ordering operator<=>(const sample_random_access_iterator&, const sample_random_access_iterator&);
friend bool operator==(const sample_random_access_iterator&, const sample_random_access_iterator&);
using difference_type = int;
using value_type = int;
using iterator_category = std::random_access_iterator_tag;
};
int main() {
f<int*>("int*");
f<const int*>("const int*");
f<std::vector<int>::iterator>("std::vector<int>::iterator");
f<sample_random_access_iterator>("sample_random_access_iterator");
std::cout << "\n";
f<int* const>("int* const");
f<std::forward_list<int>::iterator>("std::forward_list<int>::iterator");
f<std::list<int>::iterator>("std::list<int>::iterator");
f<std::istream_iterator<double>>("std::istream_iterator<double>");
f<std::ostream_iterator<double>>("std::ostream_iterator<double>");
}
出力
int* is random_access_iterator
const int* is random_access_iterator
std::vector<int>::iterator is random_access_iterator
sample_random_access_iterator is random_access_iterator
int* const is not random_access_iterator
std::forward_list<int>::iterator is not random_access_iterator
std::list<int>::iterator is not random_access_iterator
std::istream_iterator<double> is not random_access_iterator
std::ostream_iterator<double> is not random_access_iterator
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 6 ✅