Namespaces
Variants

std::equal

Von de.cppreference.net
 
 
Algorithmen-Bibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z. B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Min/Max-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
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).
1,5) Elemente werden mit operator== verglichen.
3,7) Elemente werden mit dem angegebenen binären Prädikat p verglichen.
2,4,6,8) Wie (1,3,5,7), aber ausgeführt gemäß policy.
Diese Überladungen nehmen nur dann an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks true ist:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(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:

bool pred(const Type1 &a, const Type2 &b);

Während die Signatur nicht const & haben muss, darf die Funktion die an sie übergebenen Objekte nicht verändern und muss in der Lage sein, alle Werte des Typs (möglicherweise const) Type1 und Type2 unabhängig von der Werteklasse zu akzeptieren (daher ist Type1 & nicht erlaubt, ebenso wenig wie Type1 es sei denn, für Type1 ist eine Verschiebung gleichbedeutend mit einer Kopie(seit C++11)).
Die Typen Type1 und Type2 müssen so beschaffen sein, dass Objekte der Typen InputIt1 und InputIt2 dereferenziert und dann implizit in Type1 bzw. Type2 konvertiert werden können. ​

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

1-4) Wenn jedes entsprechende Element in den beiden Bereichen gleich ist, wird true zurückgegeben. Andernfalls wird false zurückgegeben.
5-8) Wenn 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):

1) Höchstens N1 Vergleiche mit operator==.
2) O(N1) Vergleiche mit operator==.
3) Höchstens N1 Anwendungen des Prädikats p.
4) O(N1) Anwendungen des Prädikats p.
5-8) Wenn InputIt1 und InputIt2 beide LegacyRandomAccessIterator sind und last1 - first1 != last2 - first2 ist true, wird kein Vergleich durchgeführt.
Andernfalls, gegeben N als min(N1,N2):
5) Höchstens N Vergleiche mit operator==.
6) O(N) Vergleiche mit operator==.
7) Höchstens N Anwendungen des Prädikats p.
8) O(N) Anwendungen des Prädikats 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 ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jedes andere ExecutionPolicy ist 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

findet das erste Element, das bestimmte Kriterien erfüllt
(Funktionsschablone & Algorithmus-Funktionsobjekt)
vergleicht zwei Bereiche lexikografisch
(Funktionsschablone & Algorithmus-Funktionsobjekt)
findet die erste Position, an der sich zwei Bereiche unterscheiden
(Funktionsschablone & Algorithmus-Funktionsobjekt)
sucht nach dem ersten Vorkommen eines Bereichs von Elementen
(Funktionsschablone & Algorithmus-Funktionsobjekt)
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)