Namespaces
Variants

std:: distance

From ru.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 прояснено

См. также

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