std::equal
| Definiert in Header <algorithm> |
||
template< class InputIt1, class InputIt2 > bool equal( InputIt1 first1, InputIt1 last1, |
(1) | (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > bool equal( ExecutionPolicy&& policy, |
(2) | (seit C++17) |
template< class InputIt1, class InputIt2, class BinaryPred > bool equal( InputIt1 first1, InputIt1 last1, |
(3) | (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryPred > |
(4) | (seit C++17) |
template< class InputIt1, class InputIt2 > bool equal( InputIt1 first1, InputIt1 last1, |
(5) | (seit C++14) (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > bool equal( ExecutionPolicy&& policy, |
(6) | (seit C++17) |
template< class InputIt1, class InputIt2, class BinaryPred > bool equal( InputIt1 first1, InputIt1 last1, |
(7) | (seit C++14) (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryPred > |
(8) | (seit C++17) |
Prüft, ob der Bereich [first1, last1) und ein von first2 ausgehender Bereich gleich sind
- Für die Überladungen (1-4) hat der zweite Bereich std::distance(first1, last1) Elemente.
- Für die Überladungen (5-8) ist der zweite Bereich
[first2,last2).
|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> ist true. |
(bis C++20) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true. |
(seit C++20) |
Inhalt |
[edit] Parameter
| first1, last1 | - | das Iteratorenpaar, das den ersten Bereich der zu vergleichenden Elemente definiert. |
| first2, last2 | - | das Iteratorenpaar, das den zweiten Bereich der zu vergleichenden Elemente definiert. |
| policy | - | die Ausführungsrichtlinie, die verwendet werden soll |
| p | - | binäre Prädikatfunktion, die true zurückgibt, wenn die Elemente als gleich behandelt werden sollen. Die Signatur der Prädikatfunktion sollte äquivalent zur folgenden sein: bool pred(const Type1 &a, const Type2 &b); Obwohl die Signatur nicht zwingend const & haben muss, darf die Funktion die ihr übergebenen Objekte nicht modifizieren und muss alle Werte vom Typ (möglicherweise const) |
| Typanforderungen | ||
-InputIt1, InputIt2 müssen die Anforderungen an LegacyInputIterator erfüllen. | ||
-ForwardIt1, ForwardIt2 müssen die Anforderungen an LegacyForwardIterator erfüllen. | ||
-BinaryPred muss die Anforderungen an BinaryPredicate erfüllen. | ||
[edit] Rückgabewert
[edit] Komplexität
Gegeben N1 als std::distance(first1, last1) und N2 als std::distance(first2, last2)
InputIt1 und InputIt2 beide LegacyRandomAccessIterator sind und last1 - first1 != last2 - first2 true ist, werden keine Vergleiche durchgeführt.[edit] Ausnahmen
Die Überladungen mit einem Template-Parameter namens ExecutionPolicy berichten Fehler wie folgt
- Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und
ExecutionPolicyeine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist das Verhalten implementierungsabhängig. - Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.
[edit] Mögliche Implementierung
| equal (1) |
|---|
template<class InputIt1, class InputIt2> constexpr //< since C++20 bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) { for (; first1 != last1; ++first1, ++first2) if (!(*first1 == *first2)) return false; return true; } |
| equal (3) |
template<class InputIt1, class InputIt2, class BinaryPred> constexpr //< since C++20 bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPred p) { for (; first1 != last1; ++first1, ++first2) if (!p(*first1, *first2)) return false; return true; } |
| equal (5) |
namespace detail { // random-access iterator implementation (allows quick range size detection) template<class RandomIt1, class RandomIt2> constexpr //< since C++20 bool equal(RandomIt1 first1, RandomIt1 last1, RandomIt2 first2, RandomIt2 last2, std::random_access_iterator_tag, std::random_access_iterator_tag) { if (last1 - first1 != last2 - first2) return false; for (; first1 != last1; ++first1, ++first2) if (!(*first1 == *first2)) return false; return true; } // input iterator implementation (needs to manually compare with “last2”) template<class InputIt1, class InputIt2> constexpr //< since C++20 bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, std::input_iterator_tag, std::input_iterator_tag) { for (; first1 != last1 && first2 != last2; ++first1, ++first2) if (!(*first1 == *first2)) return false; return first1 == last1 && first2 == last2; } } template<class InputIt1, class InputIt2> constexpr //< since C++20 bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) { details::equal(first1, last1, first2, last2, typename std::iterator_traits<InputIt1>::iterator_category(), typename std::iterator_traits<InputIt2>::iterator_category()); } |
| equal (7) |
namespace detail { // random-access iterator implementation (allows quick range size detection) template<class RandomIt1, class RandomIt2, class BinaryPred> constexpr //< since C++20 bool equal(RandomIt1 first1, RandomIt1 last1, RandomIt2 first2, RandomIt2 last2, BinaryPred p, std::random_access_iterator_tag, std::random_access_iterator_tag) { if (last1 - first1 != last2 - first2) return false; for (; first1 != last1; ++first1, ++first2) if (!p(*first1, *first2)) return false; return true; } // input iterator implementation (needs to manually compare with “last2”) template<class InputIt1, class InputIt2, class BinaryPred> constexpr //< since C++20 bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPred p, std::input_iterator_tag, std::input_iterator_tag) { for (; first1 != last1 && first2 != last2; ++first1, ++first2) if (!p(*first1, *first2)) return false; return first1 == last1 && first2 == last2; } } template<class InputIt1, class InputIt2, class BinaryPred> constexpr //< since C++20 bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPred p) { details::equal(first1, last1, first2, last2, p, typename std::iterator_traits<InputIt1>::iterator_category(), typename std::iterator_traits<InputIt2>::iterator_category()); } |
[edit] Anmerkungen
std::equal sollte nicht verwendet werden, um die Bereiche zu vergleichen, die von den Iteratoren von 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 die gleichen Elemente enthalten.
Beim Vergleichen ganzer Container oder String-Views(seit C++17) auf Gleichheit werden in der Regel die operator== für den entsprechenden Typ bevorzugt.
Sequenzielles std::equal ist nicht garantiert kurzschließend. Z.B. wenn das erste Elementpaar beider Bereiche nicht gleich ist, können auch die restlichen Elemente verglichen werden. Ein nicht-kurzschließender Vergleich kann stattfinden, wenn die Bereiche mit std::memcmp oder implementierungsspezifischen vektorisierten Algorithmen verglichen werden.
[edit] Beispiel
Der folgende Code verwendet std::equal, um zu testen, ob ein String ein Palindrom ist.
#include <algorithm> #include <iomanip> #include <iostream> #include <string_view> constexpr bool is_palindrome(const std::string_view& s) { return std::equal(s.cbegin(), s.cbegin() + s.size() / 2, s.crbegin()); } void test(const std::string_view& s) { std::cout << std::quoted(s) << (is_palindrome(s) ? " is" : " is not") << " a palindrome\n"; } int main() { test("radar"); test("hello"); }
Ausgabe
"radar" is a palindrome "hello" is not a palindrome
[edit] Siehe auch
| (C++11) |
Findet das erste Element, das bestimmte Kriterien erfüllt (Funktionstempelat) |
| gibt true zurück, wenn ein Bereich lexikographisch kleiner als ein anderer ist (Funktionsvorlage) | |
| Findet die erste Position, an der sich zwei Bereiche unterscheiden (Funktionstempelat) | |
| Sucht nach dem ersten Vorkommen eines Elementbereichs (Funktionstempelat) | |
| (C++20) |
Bestimmt, ob zwei Elementmengen gleich sind (Algorithmus-Funktionsobjekt) |
| Funktions-Objekt, das x == y implementiert (Klassen-Template) | |
| gibt den Bereich von Elementen zurück, die einem bestimmten Schlüssel entsprechen (Funktionstemplate) |