std::ranges::equal
Определено в заголовке <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) | (с 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) | (с C++20) |
true если спроецированные значения диапазона [first1, last1) равны спроецированным значениям диапазона [first2, last2), и false в противном случае.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, потому что порядок, в котором элементы хранятся в этих контейнерах, может отличаться, даже если оба контейнера хранят одни и те же элементы.
При сравнении целых контейнеров на равенство, обычно предпочтительнее использовать operator== для соответствующих контейнеров.
Сложность
Максимально 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
См. также
|
(C++20)(C++20)(C++20) | находит первый элемент, удовлетворяющий определенным критериям (niebloid) |
|
(C++20) | возвращает true, если один диапазон лексикографически меньше другого(niebloid) |
|
(C++20) | находит первую позицию, где два диапазона отличаются (niebloid) |
|
(C++20) | ищет диапазон элементов (niebloid) |
|
(C++20) | возвращает диапазон элементов, соответствующих определенному ключу (niebloid) |
объект функции, реализующий x == y (шаблон класса) |
|
| определяет, являются ли два набора элементов одинаковыми (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/ranges/equal