Namespaces
Variants

std::ranges::equal

De fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur les intervalles (C++20)
Algorithmes contraints, par ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modificatrices    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modificatrices
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Tri et opérations connexes
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur intervalles partitionnés)
Opérations d'ensemble (sur intervalles triés)
Opérations de fusion (sur intervalles triés)
Opérations de tas
Opérations de minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Algorithmes contraints
Tous les noms dans ce menu appartiennent à l'espace de noms std::ranges
Opérations de séquence non modificatrices
Opérations de séquence modificatrices
Opérations de partitionnement
Opérations de tri
Opérations de recherche binaire (sur intervalles triés)
       
       
Opérations d'ensemble (sur intervalles triés)
Opérations de tas
Opérations de minimum/maximum
       
       
Opérations de permutation
Opérations de pliage
Opérations sur le stockage non initialisé
Types de retour
 
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)
1) Retourne true si les valeurs projetées de l'intervalle [first1last1) sont égales aux valeurs projetées de l'intervalle [first2last2), et false sinon.
2) Identique à (1), mais utilise 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 :

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 [first1last1) n'est pas égale à la longueur de l'intervalle [first2last2), 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

trouve le premier élément satisfaisant des critères spécifiques
(objet fonction d'algorithme)
compare deux intervalles lexicographiquement
(objet fonction d'algorithme)
trouve la première position où deux intervalles diffèrent
(objet fonction d'algorithme)
recherche la première occurrence d'un intervalle d'éléments
(objet fonction d'algorithme)
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)