Namespaces
Variants

std::ranges:: distance

From cppreference.net
Iterator library
Iterator concepts
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, std:: sentinel_for < I > S >

requires ( ! std:: sized_sentinel_for < S, I > )
constexpr std:: iter_difference_t < I >

distance ( I first, S last ) ;
(1) (C++20부터)
template < class I, std:: sized_sentinel_for < std:: decay_t < I >> S >

constexpr std:: iter_difference_t < std:: decay_t < I >>

distance ( I && first, S last ) ;
(2) (C++20부터)
template < ranges:: range R >

constexpr ranges:: range_difference_t < R >

distance ( R && r ) ;
(3) (C++20부터)
1,2) first 에서 last 까지의 홉 수를 반환합니다.
3) r 의 크기를 부호 있는 정수로 반환합니다.

이 페이지에서 설명하는 함수형 개체들은 algorithm function objects (일반적으로 niebloids 로 알려진)입니다. 즉:

목차

매개변수

first - 첫 번째 요소를 가리키는 iterator
last - 범위의 끝을 나타내는 sentinel first 가 가리키는
r - 거리를 계산할 범위

반환값

1) first 에서 last 까지 가는 데 필요한 증가 횟수.
2) last - static_cast < const std:: decay_t < I > & > ( first ) .
3) 만약 R ranges:: sized_range 를 모델링하면 ranges:: size ( r ) 를 반환하고, 그렇지 않으면 ranges :: distance ( ranges:: begin ( r ) , ranges:: end ( r ) ) 를 반환합니다.

복잡도

1) 선형.
2) 상수.
3) 만약 R ranges:: sized_range 를 모델링하거나 std:: sized_sentinel_for < ranges:: sentinel_t < R > , ranges:: iterator_t < R >> 가 모델링된 경우, 복잡도는 상수입니다; 그렇지 않으면 선형입니다.

가능한 구현

struct distance_fn
{
    template<class I, std::sentinel_for<I> S>
        requires (!std::sized_sentinel_for<S, I>)
    constexpr std::iter_difference_t<I> operator()(I first, S last) const
    {
        std::iter_difference_t<I> result = 0;
        while (first != last)
        {
            ++first;
            ++result;
        }
        return result;
    }
    template<class I, std::sized_sentinel_for<std::decay<I>> S>
    constexpr std::iter_difference_t<I> operator()(const I& first, S last) const
    {
        return last - first;
    }
    template<ranges::range R>
    constexpr ranges::range_difference_t<R> operator()(R&& r) const
    {
        if constexpr (ranges::sized_range<std::remove_cvref_t<R>>)
            return static_cast<ranges::range_difference_t<R>>(ranges::size(r));
        else
            return (*this)(ranges::begin(r), ranges::end(r));
    }
};
inline constexpr auto distance = distance_fn{};

예제

#include <cassert>
#include <forward_list>
#include <iterator>
#include <vector>
int main() 
{
    std::vector<int> v{3, 1, 4};
    assert(std::ranges::distance(v.begin(), v.end()) == 3);
    assert(std::ranges::distance(v.end(), v.begin()) == -3);
    assert(std::ranges::distance(v) == 3);
    std::forward_list<int> l{2, 7, 1};
    // auto size = std::ranges::size(l); // error: not a sizable range
    auto size = std::ranges::distance(l); // OK, but aware O(N) complexity
    assert(size == 3);
}

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 3392 C++20 오버로드 (1) 이 반복자를 값으로 취하므로 이동 전용
반복자 lvalue와 크기 지정 sentinel이 거부됨
오버로드 (2) 추가됨
LWG 3664 C++20 LWG 이슈 3392 의 해결책으로 인해
ranges::distance 가 배열 인수를 거부함
배열 인수를 허용함

참고 항목

주어진 거리만큼 또는 주어진 경계까지 반복자를 전진시킴
(알고리즘 함수 객체)
특정 조건을 만족하는 요소의 개수를 반환함
(알고리즘 함수 객체)
두 반복자 사이의 거리를 반환함
(함수 템플릿)