std::ranges:: equal
std::ranges
| Non-modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Partitioning operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sorting operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Binary search operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Set operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Heap operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Minimum/maximum operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Permutation operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Fold operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Operations on uninitialized storage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Return types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definiert in Header
<algorithm>
|
||
|
Aufrufsignatur
|
||
|
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 werden als gleich betrachtet, 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 algorithm function objects (informell bekannt als niebloids ), das heißt:
- Explizite Template-Argumentlisten können beim Aufruf keiner von ihnen angegeben werden.
- Keiner von ihnen ist sichtbar für argument-dependent lookup .
- Wenn einer von ihnen durch normal unqualified lookup als Name links vom Funktionsaufruf-Operator gefunden wird, wird argument-dependent lookup unterdrückt.
Inhaltsverzeichnis |
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äres Prädikat, das auf die projizierten Elemente angewendet wird |
| proj1 | - | Projektion, die auf den ersten Elementbereich angewendet wird |
| proj2 | - | Projektion, die auf den zweiten Elementbereich angewendet wird |
Rückgabewert
Wenn die Länge des Bereichs
[
first1
,
last1
)
nicht der Länge des Bereichs
[
first2
,
last2
)
entspricht, 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.
Hinweise
ranges::equal
sollte nicht verwendet werden, um die Bereiche zu vergleichen, die von den Iteratoren aus
std::unordered_set
,
std::unordered_multiset
,
std::unordered_map
oder
std::unordered_multimap
gebildet werden, da die Reihenfolge, in der die Elemente in diesen Containern gespeichert sind, unterschiedlich sein kann, selbst wenn die beiden Container dieselben Elemente speichern.
Beim Vergleich ganzer Container oder String-Views auf Gleichheit, operator == für den entsprechenden Typ werden normalerweise bevorzugt.
ranges::equal
ist nicht garantiert kurzschließend. Z.B. wenn die ersten Elementpaare beider Bereiche nicht gleich verglichen werden, können auch die restlichen Elemente verglichen werden. Nicht-kurzschließende Vergleiche können auftreten, wenn die Bereiche mit
std::memcmp
oder implementationsspezifischen vektorisierten Algorithmen verglichen werden.
Komplexität
Höchstens min ( last1 - first1, last2 - first2 ) Anwendungen des Prädikats und entsprechender Projektionen.
Wenn jedoch sowohl S1 als auch S2 std::sized_sentinel_for für ihre jeweiligen Iteratoren modellieren, und last1 - first1 ! = last2 - first2 , dann werden keine Anwendungen des Prädikats durchgeführt (Größenunterschied wird erkannt, ohne dass Elemente betrachtet werden).
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; |
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
Siehe auch
|
(C++20)
(C++20)
(C++20)
|
findet das erste Element, das bestimmte Kriterien erfüllt
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
gibt
true
zurück, falls ein Bereich lexikographisch kleiner als ein anderer ist
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
findet die erste Position, an der zwei Bereiche sich unterscheiden
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
sucht nach dem ersten Vorkommen eines Bereichs von Elementen
(Algorithmus-Funktionsobjekt) |
|
(C++20)
|
gibt den Bereich der Elemente zurück, die einem spezifischen Schlüssel entsprechen
(Algorithmus-Funktionsobjekt) |
|
Funktionsobjekt, das
x
==
y
implementiert
(Klassentemplate) |
|
|
bestimmt, ob zwei Mengen von Elementen identisch sind
(Funktionstemplate) |