std::ranges::equal
| Défini dans l'en-tête <algorithm>
|
||
| Signature d'appel |
||
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) | (depuis 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) | (depuis C++20) |
true si les valeurs projetées de l'intervalle [first1, last1) sont égales aux valeurs projetées de l'intervalle [first2, last2), et false sinon.r comme intervalle source, comme si ranges::begin(r) était utilisé comme first et ranges::end(r) comme last.Deux intervalles sont considérés égaux s'ils ont le même nombre d'éléments et que chaque paire d'éléments projetés correspondants satisfait pred. C'est-à-dire que std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2)) retourne true pour toutes les paires d'éléments correspondants dans les deux intervalles.
Les entités de type fonction décrites sur cette page sont des objets fonctions d'algorithme (informellement appelés niebloids), c'est-à-dire :
- Les listes explicites d'arguments template ne peuvent pas être spécifiées lors de leur appel.
- Aucune d'entre elles n'est visible par la recherche dépendante des arguments.
- Lorsque l'une d'elles est trouvée par la recherche non qualifiée normale comme nom à gauche de l'opérateur d'appel de fonction, la recherche dépendante des arguments est inhibée.
Paramètres
| first1, last1 | - | la paire itérateur-sentinelle définissant le premier intervalle d'éléments à comparer |
| r1 | - | le premier intervalle des éléments à comparer |
| first2, last2 | - | la paire itérateur-sentinelle définissant le second intervalle d'éléments à comparer |
| r2 | - | le second intervalle des éléments à comparer |
| pred | - | prédicat binaire à appliquer aux éléments projetés |
| proj1 | - | projection à appliquer au premier intervalle d'éléments |
| proj2 | - | projection à appliquer au second intervalle d'éléments |
Valeur de retour
Si la longueur de l'intervalle [first1, last1) n'est pas égale à la longueur de l'intervalle [first2, last2), retourne false.
Si les éléments des deux intervalles sont égaux après projection, retourne true.
Sinon, retourne false.
Notes
ranges::equal ne doit pas être utilisé pour comparer les intervalles formés par les itérateurs de std::unordered_set, std::unordered_multiset, std::unordered_map ou std::unordered_multimap car l'ordre dans lequel les éléments sont stockés dans ces conteneurs peut être différent même si les deux conteneurs stockent les mêmes éléments.
Lors de la comparaison de conteneurs entiers ou de vues de chaînes pour l'égalité, operator== pour le type correspondant est généralement préféré.
ranges::equal n'est pas garanti d'être court-circuité. Par ex. si la première paire d'éléments des deux intervalles n'est pas égale, le reste des éléments peut aussi être comparé. Une comparaison non court-circuitée peut se produire lorsque les intervalles sont comparés avec std::memcmp ou des algorithmes vectorisés spécifiques à l'implémentation.
Complexité
Au plus min(last1 - first1, last2 - first2) applications du prédicat et des projections correspondantes.
Cependant, si S1 et S2 modélisent tous deux std::sized_sentinel_for leurs itérateurs respectifs, et last1 - first1 != last2 - first2 alors aucune application du prédicat n'est effectuée (la différence de taille est détectée sans examiner aucun élément).
Implémentation possible
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;
|
Exemple
Le code suivant utilise ranges::equal pour tester si une chaîne est un palindrome.
#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"));
}
Sortie :
"radar" is a palindrome
"hello" is not a palindrome
Voir aussi
(C++20)(C++20)(C++20) |
trouve le premier élément satisfaisant des critères spécifiques (objet fonction d'algorithme) |
| compare deux intervalles lexicographiquement (objet fonction d'algorithme) | |
(C++20) |
trouve la première position où deux intervalles diffèrent (objet fonction d'algorithme) |
(C++20) |
recherche la première occurrence d'un intervalle d'éléments (objet fonction d'algorithme) |
(C++20) |
trouve l'intervalle d'éléments correspondant à la valeur donnée en utilisant la recherche binaire (objet fonction d'algorithme) |
objet fonction implémentant x == y (class template) | |
| détermine si deux ensembles d'éléments sont identiques (function template) |