std::ranges::equal
| Definiert in Header <algorithm>
|
||
| Aufrufsignatur |
||
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
equal( I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
Proj1 proj1 = {}, Proj2 proj2 = {} );
|
(1) | (seit C++20) |
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
equal( R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
|
(2) | (seit C++20) |
true zurück, wenn die projizierten Werte des Bereichs [first1, last1) gleich den projizierten Werten des Bereichs [first2, last2) sind, andernfalls false.r als Quellbereich, als ob ranges::begin(r) als first und ranges::end(r) als last verwendet würden.Zwei Bereiche gelten als gleich, wenn sie die gleiche Anzahl von Elementen haben und jedes Paar korrespondierender 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 korrespondierender Elemente in beiden Bereichen zurück.
Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithmus-Funktionsobjekte (informell als Niebloids bekannt), das heißt:
- Explizite Vorlagenargumentlisten können beim Aufruf keiner von ihnen angegeben werden.
- Keine von ihnen sind für argumentabhängige Suche sichtbar.
- Wenn eine von ihnen durch normale unqualifizierte Suche als Name links vom Funktionsaufrufoperator gefunden wird, wird argumentabhängige Suche unterdrückt.
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 Bereich von Elementen angewendet wird |
| proj2 | - | Projektion, die auf den zweiten Bereich von Elementen angewendet wird |
Rückgabewert
Wenn die Länge des Bereichs [first1, last1) nicht gleich der Länge des Bereichs [first2, last2) ist, 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 durch die 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 speichern.
Beim Vergleichen ganzer Container oder String-Views auf Gleichheit werden normalerweise operator== für den entsprechenden Typ bevorzugt.
ranges::equal ist nicht garantiert kurzschließend. Z.B. wenn die ersten Elementpaare beider Bereiche nicht gleich sind, können die restlichen Elemente trotzdem verglichen werden. Ein nicht kurzschließender Vergleich kann auftreten, wenn die Bereiche mit std::memcmp oder implementierungsspezifischen vektorisierten Algorithmen verglichen werden.
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, dann werden keine Anwendungen des Prädikats vorgenommen (Größenunterschied wird erkannt, ohne Elemente anzusehen).
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) |
| vergleicht zwei Bereiche lexikografisch (Algorithmus-Funktionsobjekt) | |
(C++20) |
findet die erste Position, an der sich zwei Bereiche unterscheiden (Algorithmus-Funktionsobjekt) |
(C++20) |
sucht nach dem ersten Vorkommen eines Bereichs von Elementen (Algorithmus-Funktionsobjekt) |
(C++20) |
findet den Bereich von Elementen, die dem gegebenen Wert entsprechen, mittels binärer Suche (Algorithmus-Funktionsobjekt) |
Funktionsobjekt, das x == y implementiert (Klassenvorlage) | |
| bestimmt, ob zwei Mengen von Elementen gleich sind (Funktionsvorlage) |