Namespaces
Variants

std::ranges::equal

С ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Немодифицирующие операции над последовательностями    
Пакетные операции
(C++17)
Операции поиска
Модифицирующие операции над последовательностями
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(until C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разделения
(C++11)    

Операции сортировки
Операции бинарного поиска
(по разделённым диапазонам)
Операции над множествами (на сортированных диапазонах)
Операции слияния (на сортированных диапазонах)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановки


Политики выполнения (C++17)
(только для демонстрации*)(C++26)

Числовые операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Ограниченные алгоритмы
Все имена в этом меню принадлежат пространству имён std::ranges
Немодифицирующие операции над последовательностями
Модифицирующие операции над последовательностями
Операции разделения
Операции сортировки
Операции бинарного поиска (на сортированных диапазонах)
       
       
Операции над множествами (на сортированных диапазонах)
Операции с кучей
Операции минимума/максимума
       
       
Операции перестановки
Операции свёртки
Операции с неинициализированной памятью
Типы возвращаемых значений
 
Определено в заголовке <algorithm>
Сигнатура вызова
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) (since 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) (since C++20)
1) Возвращает true, если проецированные значения диапазона [first1, last1) равны проецированным значениям диапазона [first2, last2), и false в противном случае.
2) То же, что и (1), но использует r в качестве исходного диапазона, как если бы использовался ranges::begin(r) как first и ranges::end(r) как last.

Два диапазона считаются равными, если они имеют одинаковое количество элементов и каждая пара соответствующих проецированных элементов удовлетворяет pred. То есть std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2)) возвращает true для всех пар соответствующих элементов в обоих диапазонах.

Функциональные объекты, описанные на этой странице, являются функциональными объектами алгоритмов (неофициально называемые niebloids), то есть:

Параметры

first1, last1 - пара итератор-сентинель, определяющая первый диапазон элементов для сравнения
r1 - первый диапазон элементов для сравнения
first2, last2 - пара итератор-сентинель, определяющая второй диапазон элементов для сравнения
r2 - второй диапазон элементов для сравнения
pred - бинарный предикат, применяемый к проецированным элементам
proj1 - проекция, применяемая к первому диапазону элементов
proj2 - проекция, применяемая ко второму диапазону элементов

Возвращаемое значение

Если длина диапазона [first1, last1) не равна длине диапазона [first2, last2), возвращает false.

Если элементы в двух диапазонах равны после проекции, возвращает true.

В противном случае возвращает false.

Примечания

ranges::equal не следует использовать для сравнения диапазонов, образованных итераторами из std::unordered_set, std::unordered_multiset, std::unordered_map или std::unordered_multimap, поскольку порядок хранения элементов в этих контейнерах может различаться, даже если два контейнера хранят одни и те же элементы.

При сравнении целых контейнеров или string_view на равенство обычно предпочитают operator== для соответствующего типа.

ranges::equal не гарантирует короткого замыкания. Например, если первые пары элементов обоих диапазонов не равны, остальные элементы также могут быть сравнены. Сравнение без короткого замыкания может произойти, когда диапазоны сравниваются с помощью std::memcmp или реализации конкретных векторизованных алгоритмов.

Сложность

Не более min(last1 - first1, last2 - first2) применений предиката и соответствующих проекций.

Однако, если S1 и S2 оба моделируют std::sized_sentinel_for свои соответствующие итераторы, и last1 - first1 != last2 - first2 то не производится ни одного применения предиката (несоответствие размеров обнаруживается без просмотра элементов).

Возможная реализация

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;

Пример

Следующий код использует ranges::equal для проверки, является ли строка палиндромом.

#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"));
}

Вывод:

"radar" is a palindrome
"hello" is not a palindrome

Смотри также

находит первый элемент, удовлетворяющий определённым критериям
(функциональный объект алгоритма)
сравнивает два диапазона лексикографически
(функциональный объект алгоритма)
находит первую позицию, где два диапазона различаются
(функциональный объект алгоритма)
ищет первое вхождение диапазона элементов
(функциональный объект алгоритма)
находит диапазон элементов, соответствующих заданному значению, используя бинарный поиск
(функциональный объект алгоритма)
функциональный объект, реализующий x == y
(шаблон класса)
определяет, являются ли два набора элементов одинаковыми
(шаблон функции)