Namespaces
Variants

std:: 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 InputIt >

typename std:: iterator_traits < InputIt > :: difference_type

distance ( InputIt first, InputIt last ) ;
(constexpr начиная с C++17)

Возвращает количество переходов от first до last .

Если InputIt не является LegacyRandomAccessIterator , поведение не определено, если last не является достижимым из first .

Если InputIt является LegacyRandomAccessIterator , поведение не определено, если first и last недостижимы друг из друга.

Содержание

Параметры

first - итератор, указывающий на первый элемент
last - итератор, указывающий на конец диапазона
Требования к типам
-
InputIt должен соответствовать требованиям LegacyInputIterator . Операция более эффективна, если InputIt дополнительно соответствует требованиям LegacyRandomAccessIterator .

Возвращаемое значение

Количество инкрементов, необходимых для перехода от first к last .

Значение может быть отрицательным, если используются итераторы произвольного доступа и first достижим из last .

(since C++11)

Сложность

Линейный.

Однако, если InputIt дополнительно удовлетворяет требованиям LegacyRandomAccessIterator , сложность становится постоянной.

Возможная реализация

Смотрите также реализации в libstdc++ и libc++ .

Реализация C++98 с использованием диспетчеризации тегов, с constexpr удалённым
namespace detail
{
    template<class It>
    constexpr // required since C++17
    typename std::iterator_traits<It>::difference_type 
        do_distance(It first, It last, std::input_iterator_tag)
    {
        typename std::iterator_traits<It>::difference_type result = 0;
        while (first != last)
        {
            ++first;
            ++result;
        }
        return result;
    }
    template<class It>
    constexpr // required since C++17
    typename std::iterator_traits<It>::difference_type 
        do_distance(It first, It last, std::random_access_iterator_tag)
    {
        return last - first;
    }
} // namespace detail
template<class It>
constexpr // since C++17
typename std::iterator_traits<It>::difference_type 
    distance(It first, It last)
{
    return detail::do_distance(first, last,
                               typename std::iterator_traits<It>::iterator_category());
}
Реализация C++17 с использованием if constexpr
template<class It>
constexpr typename std::iterator_traits<It>::difference_type
    distance(It first, It last)
{
    using category = typename std::iterator_traits<It>::iterator_category;
    static_assert(std::is_base_of_v<std::input_iterator_tag, category>);
    if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>)
        return last - first;
    else
    {
        typename std::iterator_traits<It>::difference_type result = 0;
        while (first != last)
        {
            ++first;
            ++result;
        }
        return result;
    }
}

Пример

#include <iostream>
#include <iterator>
#include <vector>
int main() 
{
    std::vector<int> v{3, 1, 4};
    std::cout << "distance(first, last) = "
              << std::distance(v.begin(), v.end()) << '\n'
              << "distance(last, first) = "
              << std::distance(v.end(), v.begin()) << '\n';
              // поведение не определено (до LWG940)
    static constexpr auto il = {3, 1, 4};
    // Начиная с C++17 `distance` может использоваться в контексте constexpr.
    static_assert(std::distance(il.begin(), il.end()) == 3);
    static_assert(std::distance(il.end(), il.begin()) == -3);
}

Вывод:

distance(first, last) = 3
distance(last, first) = -3

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
LWG 940 C++98 формулировка была неясной для случая, когда first достижим из last прояснено

Смотрите также

перемещает итератор на заданное расстояние
(шаблон функции)
возвращает количество элементов, удовлетворяющих заданным критериям
(шаблон функции)
возвращает расстояние между итератором и стражем, или между началом и концом диапазона
(функциональный объект алгоритма)