std::equal
| Definiert in Header <algorithm>
|
||
template< class InputIt1, class InputIt2 >
bool equal( InputIt1 first1, InputIt1 last1,
InputIt2 first2 );
|
(1) | (constexpr seit C++20) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
bool equal( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2 );
|
(2) | (seit C++17) |
template< class InputIt1, class InputIt2, class BinaryPred >
bool equal( InputIt1 first1, InputIt1 last1,
InputIt2 first2, BinaryPred p );
|
(3) | (constexpr seit C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class BinaryPred >
bool equal( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, BinaryPred p );
|
(4) | (seit C++17) |
template< class InputIt1, class InputIt2 >
bool equal( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2 );
|
(5) | (seit C++14) (constexpr seit C++20) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
bool equal( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2 );
|
(6) | (seit C++17) |
template< class InputIt1, class InputIt2, class BinaryPred >
bool equal( InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2, BinaryPred p );
|
(7) | (seit C++14) (constexpr seit C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class BinaryPred >
bool equal( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2, BinaryPred p );
|
(8) | (seit C++17) |
Überprüft, ob [first1, last1) und ein Bereich, der bei first2 beginnt, gleich sind:
- Für Überladungen (1-4) hat der zweite Bereich
std::distance(first1, last1)Elemente. - Für Überladungen (5-8) ist der zweite Bereich
[first2,last2).
operator== verglichen.p verglichen.policy.true ist:
|
|
(bis C++20) |
|
|
(seit C++20) |
Parameter
| first1, last1 | - | das Paar von Iteratoren, das den ersten Bereich der zu vergleichenden Elemente definiert |
| first2, last2 | - | das Paar von Iteratoren, das den zweiten Bereich der zu vergleichenden Elemente definiert |
| policy | - | die zu verwendende Ausführungsrichtlinie |
| p | - | binäres Prädikat, das true zurückgibt, wenn die Elemente als gleich behandelt werden sollen. Die Signatur der Prädikatfunktion sollte wie folgt aussehen:
Während die Signatur nicht |
| Typanforderungen | ||
-InputIt1, InputIt2 muss die Anforderungen von LegacyInputIterator erfüllen.
| ||
-ForwardIt1, ForwardIt2 muss die Anforderungen von LegacyForwardIterator erfüllen.
| ||
-BinaryPred muss die Anforderungen von BinaryPredicate erfüllen.
| ||
Rückgabewert
true zurückgegeben. Andernfalls wird false zurückgegeben.std::distance(first1, last1) und std::distance(first2, last2) gleich sind und jedes entsprechende Element in den beiden Bereichen gleich ist, wird true zurückgegeben. Andernfalls wird false zurückgegeben.Komplexität
Gegeben N1 als std::distance(first1, last1) und N2 als std::distance(first2, last2):
operator==.operator==.p.p.InputIt1 und InputIt2 beide LegacyRandomAccessIterator sind und last1 - first1 != last2 - first2 ist true, wird kein Vergleich durchgeführt.operator==.operator==.p.p.Ausnahmen
Die Überladungen mit einem Template-Parameter namens ExecutionPolicy melden 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 jedes andereExecutionPolicyist das Verhalten implementierungsdefiniert. - Wenn der Algorithmus keinen Speicher zuweisen kann, wird std::bad_alloc ausgelöst.
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());
}
|
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 dieselben Elemente speichern.
Beim Vergleich ganzer Container oder String-Views(seit C++17) auf Gleichheit werden normalerweise operator== für den entsprechenden Typ bevorzugt.
Sequentielles std::equal ist nicht garantiert kurzschlussartig. Z. B. wenn die ersten Elementpaare beider Bereiche nicht gleich sind, können die restlichen Elemente ebenfalls verglichen werden. Ein nicht kurzschlussartiger Vergleich kann auftreten, wenn die Bereiche mit std::memcmp oder implementationsspezifischen vektorisierten Algorithmen verglichen werden.
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
Siehe auch
(C++11) |
findet das erste Element, das bestimmte Kriterien erfüllt (Funktionsschablone & Algorithmus-Funktionsobjekt) |
(C++20)(C++20)(C++20) |
|
| vergleicht zwei Bereiche lexikografisch (Funktionsschablone & Algorithmus-Funktionsobjekt) | |
| findet die erste Position, an der sich zwei Bereiche unterscheiden (Funktionsschablone & Algorithmus-Funktionsobjekt) | |
(C++20) |
|
| sucht nach dem ersten Vorkommen eines Bereichs von Elementen (Funktionsschablone & Algorithmus-Funktionsobjekt) | |
(C++20) |
|
(C++20) |
bestimmt, ob zwei Mengen von Elementen gleich sind (Algorithmus-Funktionsobjekt) |
Funktionsobjekt, das x == y implementiert (Klassenschablone) | |
| findet den Bereich von Elementen, die dem angegebenen Wert entsprechen, mittels binärer Suche (Funktionsschablone & Algorithmus-Funktionsobjekt) | |
(C++20) |