std::ranges::equal
| Definiert in Header <algorithm> |
||
| Aufruf-Signatur |
||
| template< std::input_iterator I1, std::sentinel_for<I1> S1, std::input_iterator I2, std::sentinel_for<I2> S2, |
(1) | (seit C++20) |
| template< ranges::input_range R1, ranges::input_range R2, class Pred = ranges::equal_to, |
(2) | (seit C++20) |
[first1, last1) gleich den projizierten Werten des Bereichs [first2, last2) sind, andernfalls false.Zwei Bereiche gelten als gleich, wenn sie die gleiche Anzahl von Elementen haben und jedes Paar entsprechender projizierter Elemente pred erfüllt. Das heißt, std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2)) gibt true für alle Paare entsprechender Elemente in beiden Bereichen zurück.
Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als niebloids bekannt), d.h.
- Können explizite Template-Argumentlisten bei keinem von ihnen angegeben werden.
- Keiner von ihnen ist für Argument-abhängige Suche sichtbar.
- Wenn einer von ihnen durch normale unqualifizierte Suche als Name links vom Funktionsaufrufoperator gefunden wird, wird die Argument-abhängige Suche unterdrückt.
Inhalt |
[bearbeiten] Parameter
| first1, last1 | - | das Iterator-Sentinel-Paar, das den ersten Bereich der zu vergleichenden Elemente definiert |
| r1 | - | der erste Bereich der zu vergleichenden Elemente |
| first2, last2 | - | das Iterator-Sentinel-Paar, das den zweiten Bereich der zu vergleichenden Elemente definiert |
| r2 | - | der zweite Bereich der zu vergleichenden Elemente |
| pred | - | binäre Prädikatfunktion, die auf die projizierten Elemente angewendet wird |
| proj1 | - | Projektion, die auf den ersten Bereich der Elemente angewendet wird |
| proj2 | - | Projektion, die auf den zweiten Bereich der Elemente angewendet wird |
[bearbeiten] Rückgabewert
Wenn die Länge des Bereichs [first1, last1) nicht mit der Länge des Bereichs [first2, last2) übereinstimmt, wird false zurückgegeben.
Wenn die Elemente in den beiden Bereichen nach der Projektion gleich sind, wird true zurückgegeben.
Andernfalls wird false zurückgegeben.
[bearbeiten] Hinweise
ranges::equal sollte nicht verwendet werden, um die von den Iteratoren von std::unordered_set, std::unordered_multiset, std::unordered_map oder std::unordered_multimap gebildeten Bereiche zu vergleichen, da die Reihenfolge, in der die Elemente in diesen Containern gespeichert werden, unterschiedlich sein kann, selbst wenn die beiden Container die gleichen Elemente speichern.
Beim Vergleich ganzer Container oder String-Views auf Gleichheit werden normalerweise operator== für den entsprechenden Typ bevorzugt.
ranges::equal ist nicht garantiert kurzschlussend. Wenn beispielsweise die ersten Elementpaare beider Bereiche nicht gleich sind, können auch die restlichen Elemente verglichen werden. Ein nicht kurzschlussender Vergleich kann auftreten, wenn die Bereiche mit std::memcmp oder implementierungsspezifischen vektorisierten Algorithmen verglichen werden.
[bearbeiten] Komplexität
Höchstens min(last1 - first1, last2 - first2) Anwendungen des Prädikats und der entsprechenden Projektionen.
Wenn jedoch S1 und S2 beide std::sized_sentinel_for für ihre jeweiligen Iteratoren modellieren und last1 - first1 != last2 - first2 gilt, werden keine Anwendungen des Prädikats durchgeführt (Größenunterschied wird ohne Blick auf Elemente erkannt).
[bearbeiten] Mögliche Implementierung
struct equal_fn { template<std::input_iterator I1, std::sentinel_for<I1> S1, std::input_iterator I2, std::sentinel_for<I2> S2, class Pred = ranges::equal_to, class Proj1 = std::identity, class Proj2 = std::identity> requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2> constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { if constexpr (std::sized_sentinel_for<S1, I1> and std::sized_sentinel_for<S2, I2>) if (std::ranges::distance(first1, last1) != std::ranges::distance(first2, last2)) return false; for (; first1 != last1; ++first1, (void)++first2) if (!std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) return false; return true; } template<ranges::input_range R1, ranges::input_range R2, class Pred = ranges::equal_to, class Proj1 = std::identity, class Proj2 = std::identity> requires std::indirectly_comparable<ranges::iterator_t<R1>, ranges::iterator_t<R2>, Pred, Proj1, Proj2> constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { return (*this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), std::ref(pred), std::ref(proj1), std::ref(proj2)); } }; inline constexpr equal_fn equal; |
[bearbeiten] Beispiel
Der folgende Code verwendet ranges::equal, um zu testen, ob ein String ein Palindrom ist.
#include <algorithm> #include <iomanip> #include <iostream> #include <ranges> #include <string_view> constexpr bool is_palindrome(const std::string_view s) { namespace views = std::views; auto forward = s | views::take(s.size() / 2); auto backward = s | views::reverse | views::take(s.size() / 2); return std::ranges::equal(forward, backward); } void test(const std::string_view s) { std::cout << std::quoted(s) << " is " << (is_palindrome(s) ? "" : "not ") << "a palindrome\n"; } int main() { test("radar"); test("hello"); static_assert(is_palindrome("ABBA") and not is_palindrome("AC/DC")); }
Ausgabe
"radar" is a palindrome "hello" is not a palindrome
[bearbeiten] Siehe auch
| (C++20)(C++20)(C++20) |
Findet das erste Element, das bestimmte Kriterien erfüllt (Algorithmus-Funktionsobjekt) |
| gibt true zurück, wenn ein Bereich lexikographisch kleiner als ein anderer ist (Algorithmus-Funktionsobjekt) | |
| (C++20) |
Findet die erste Position, an der sich zwei Bereiche unterscheiden (Algorithmus-Funktionsobjekt) |
| (C++20) |
Sucht nach dem ersten Vorkommen eines Elementbereichs (Algorithmus-Funktionsobjekt) |
| (C++20) |
gibt den Bereich von Elementen zurück, die einem bestimmten Schlüssel entsprechen (Algorithmus-Funktionsobjekt) |
| Funktions-Objekt, das x == y implementiert (Klassen-Template) | |
| Bestimmt, ob zwei Elementmengen gleich sind (Funktionstempelat) |