std:: distance
|
Definiert im Header
<iterator>
|
||
|
template
<
class
InputIt
>
typename
std::
iterator_traits
<
InputIt
>
::
difference_type
|
(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) |
|
|
(C++20)
|
gibt die Distanz zwischen einem Iterator und einem Sentinel zurück, oder zwischen Anfang und Ende eines Bereichs
(Algorithmus-Funktionsobjekt) |