Namespaces
Variants

std:: random_access_iterator

From cppreference.net
Iterator library
Iterator concepts
random_access_iterator
(C++20)


Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
헤더 파일에 정의됨 <iterator>
template < class I >

concept random_access_iterator =
std:: bidirectional_iterator < I > &&
std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: random_access_iterator_tag > &&
std:: totally_ordered < I > &&
std:: sized_sentinel_for < I, I > &&
requires ( I i, const I j, const std:: iter_difference_t < I > n ) {
{ i + = n } - > std:: same_as < I & > ;
{ j + n } - > std:: same_as < I > ;
{ n + j } - > std:: same_as < I > ;
{ i - = n } - > std:: same_as < I & > ;
{ j - n } - > std:: same_as < I > ;
{ j [ n ] } - > std:: same_as < std:: iter_reference_t < I >> ;

} ;
(C++20 이후)

random_access_iterator 개념은 bidirectional_iterator 를 확장하여 += , + , -= , - 연산자를 통한 상수 시간 이동 지원, - 연산자를 통한 상수 시간 거리 계산, 그리고 첨자 [] 를 이용한 배열 표기법을 추가로 지원합니다.

목차

반복자 개념 결정

이 개념의 정의는 전시 전용(exposition-only) 별칭 템플릿 /*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 ) 와 같습니다.
  • 임의의 두 양의 정수 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 해야 합니다(다르게 명시된 경우를 제외하고).

암시적 표현 변형

상수 lvalue 피연산자에 대해 비수정적인 표현식을 사용하는 requires expression 암시적 표현식 변형 도 요구합니다.

참고 사항

LegacyRandomAccessIterator 요구사항과 달리, random_access_iterator 개념은 역참조(dereference)가 lvalue를 반환할 것을 요구하지 않습니다.

예제

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);
}

참고 항목

forward_iterator 가 역방향 이동을 지원하는 양방향 반복자임을 명시
(컨셉)
random_access_iterator 가 메모리 상에서 연속적인 요소들을 참조하는 연속 반복자임을 명시
(컨셉)