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)
Definiert im Header <iterator>
template < class InputIt >

typename std:: iterator_traits < InputIt > :: difference_type

distance ( InputIt first, InputIt last ) ;
(constexpr seit C++17)

Gibt die Anzahl der Hops von first zu last zurück.

Wenn InputIt kein LegacyRandomAccessIterator ist, ist das Verhalten undefiniert, wenn last nicht von first aus erreichbar ist.

Wenn InputIt ein LegacyRandomAccessIterator ist, ist das Verhalten undefiniert, wenn first und last nicht voneinander erreichbar sind.

Inhaltsverzeichnis

Parameter

first - Iterator, der auf das erste Element zeigt
last - Iterator, der auf das Ende des Bereichs zeigt
Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen. Die Operation ist effizienter, wenn InputIt zusätzlich die Anforderungen von LegacyRandomAccessIterator erfüllt.

Rückgabewert

Die Anzahl der Inkremente, die benötigt werden, um von first zu last zu gelangen.

Der Wert kann negativ sein, wenn Random-Access-Iteratoren verwendet werden und first von last erreichbar ist.

(since C++11)

Komplexität

Linear.

Wenn jedoch InputIt zusätzlich die Anforderungen von LegacyRandomAccessIterator erfüllt, ist die Komplexität konstant.

Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ und libc++ .

C++98-Implementierung mittels Tag-Dispatch, mit entferntem 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-Implementierung mittels 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;
    }
}

Beispiel

#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';
              // the behavior is undefined (until LWG940)
    static constexpr auto il = {3, 1, 4};
    // Since C++17 `distance` can be used in constexpr context.
    static_assert(std::distance(il.begin(), il.end()) == 3);
    static_assert(std::distance(il.end(), il.begin()) == -3);
}

Ausgabe:

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

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 940 C++98 die Formulierung war unklar für den Fall, wo first von last erreichbar ist klargestellt

Siehe auch

rückt einen Iterator um eine gegebene Distanz vor
(Funktions-Template)
gibt die Anzahl der Elemente zurück, die bestimmte Kriterien erfüllen
(Funktions-Template)
gibt die Distanz zwischen einem Iterator und einem Sentinel zurück, oder zwischen Anfang und Ende eines Bereichs
(Algorithmus-Funktionsobjekt)