Namensräume
Varianten
Aktionen

std::ranges::distance

Von cppreference.com
< cpp‎ | iterator
 
 
Iterator-Bibliothek
Iterator-Konzepte
Iterator-Primitive
Algorithmus-Konzepte und Hilfsprogramme
Indirekte aufrufbare Konzepte
Gemeinsame Algorithmus-Anforderungen
(C++20)
(C++20)
(C++20)
Dienstprogramme
(C++20)
Iterator-Adapter
Iterator-Operationen
(C++11)  
(C++11)
ranges::distance
(C++20)
Bereichszugriff
(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 in Header <iterator>
Aufruf-Signatur
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) (seit 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) (seit C++20)
template< ranges::range R >

constexpr ranges::range_difference_t<R>

    distance( R&& r );
(3) (seit C++20)
1,2) Gibt die Anzahl der Schritte von first nach last zurück.
3) Gibt die Größe von r als vorzeichenbehafteten Integer zurück.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.

Inhalt

[edit] Parameter

first - Iterator, der auf das erste Element zeigt
last - Sentinel, der das Ende des Bereichs von first kennzeichnet
r - Bereich, dessen Distanz berechnet werden soll

[edit] Rückgabewert

1) Die Anzahl der Inkremente, die benötigt werden, um von first nach last zu gelangen.
2) last - static_cast<const std::decay_t<I>&>(first).
3) Wenn R ranges::sized_range modelliert, gibt ranges::size(r) zurück; andernfalls ranges::distance(ranges::begin(r), ranges::end(r)).

[edit] Komplexität

1) Linear.
2) Konstant.
3) Wenn R ranges::sized_range modelliert oder wenn std::sized_sentinel_for<ranges::sentinel_t<R>, ranges::iterator_t<R>> modelliert wird, ist die Komplexität konstant; andernfalls linear.

[edit] Mögliche Implementierung

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

[edit] Beispiel

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

[edit] 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 3392 C++20 Überladung (1) nimmt Iterator per Wert, also Move-only
Iterator-Lvalue mit einem sized sentinel wurde abgelehnt
hinzugefügte Überladung (2)
LWG 3664 C++20 Die Lösung für LWG issue 3392 machte
ranges::distance Array-Argumente abgelehnt
akzeptiert sie

[edit] Siehe auch

bewegt einen Iterator um die angegebene Distanz vorwärts oder zu einer gegebenen Grenze
(Algorithmus-Funktionsobjekt)[bearbeiten]
Gibt die Anzahl der Elemente zurück, die bestimmte Kriterien erfüllen
(Algorithmus-Funktionsobjekt)[edit]
gibt die Distanz zwischen zwei Iteratoren zurück
(Funktionsvorlage) [bearbeiten]