std::ranges::find, std::ranges::find_if, std::ranges::find_if_not
Defined in header <algorithm> |
||
|---|---|---|
| Call signature | ||
template< std::input_iterator I, std::sentinel_for<I> S,
class T, class Proj = std::identity >
requires std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>,
const T*>
constexpr I
find( I first, S last, const T& value, Proj proj = {} ); |
(1) | (since C++20) |
template< ranges::input_range R, class T, class Proj = std::identity >
requires std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>,
const T*>
constexpr ranges::borrowed_iterator_t<R>
find( R&& r, const T& value, Proj proj = {} );
|
(2) | (since C++20) |
template< std::input_iterator I, std::sentinel_for<I> S,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
constexpr I
find_if( I first, S last, Pred pred, Proj proj = {} ); |
(3) | (since C++20) |
template< ranges::input_range R, class Proj = std::identity,
std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>,
Proj>> Pred >
constexpr ranges::borrowed_iterator_t<R>
find_if( R&& r, Pred pred, Proj proj = {} );
|
(4) | (since C++20) |
template< std::input_iterator I, std::sentinel_for<I> S,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
constexpr I
find_if_not( I first, S last, Pred pred, Proj proj = {} ); |
(5) | (since C++20) |
template< ranges::input_range R, class Proj = std::identity,
std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>,
Proj>> Pred >
constexpr ranges::borrowed_iterator_t<R>
find_if_not( R&& r, Pred pred, Proj proj = {} );
|
(6) | (since C++20) |
Возвращает первый элемент в диапазоне [first, last) , удовлетворяющий определенным критериям:
1)
find ищет элемент, равный value.
3)
find_if ищет элемент, для которого предикат pred возвращает true.
5)
find_if_not ищет элемент, для которого предикат pred возвращает false.
2,4,6) Аналогично (1,3,5), но использует
r в качестве исходного диапазона, как если бы использовали ranges::begin(r) в качестве first и ranges::end(r) в качестве last.Функции, описанные на этой странице, являются niebloids, то есть:
- Явные списки шаблонных аргументов не могут быть указаны при их вызове.
- Они не видны для поиска зависимого от аргументов.
- Когда любая из них обнаружена обычным поиском без квалификаторов в качестве имени слева от оператора вызова функции, поиск зависимый от аргументов заблокирован.
На практике они могут быть реализованы в виде объектов-функций или с помощью специальных расширений компилятора.
Параметры
| first, last | - | диапазон элементов для проверки |
| r | - | диапазон элементов для проверки |
| value | - | значение для сравнения с элементами |
| pred | - | предикат для применения к проецированным элементам |
| proj | - | проекция для применения к элементам |
Значение результата
Итератор на первый элемент, удовлетворяющий условию, или итератор, равный last, если такой элемент не найден.
Сложность
Максимум last - first применений предиката и проекции.
Возможная реализация
| find |
|---|
struct find_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
class T, class Proj = std::identity>
requires std::indirect_binary_predicate<
ranges::equal_to, std::projected<I, Proj>, const T*>
constexpr I operator()(I first, S last, const T& value, Proj proj = {}) const
{
for (; first != last; ++first)
if (std::invoke(proj, *first) == value)
return first;
return first;
}
template<ranges::input_range R, class T, class Proj = std::identity>
requires std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T*>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, const T& value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), value, std::ref(proj));
}
};
inline constexpr find_fn find; |
| find_if |
struct find_if_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
constexpr I operator()(I first, S last, Pred pred, Proj proj = {}) const
{
for (; first != last; ++first)
if (std::invoke(pred, std::invoke(proj, *first)))
return first;
return first;
}
template<ranges::input_range R, class Proj = std::identity,
std::indirect_unary_predicate<
std::projected<ranges::iterator_t<R>, Proj>> Pred>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, Pred pred, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj));
}
};
inline constexpr find_if_fn find_if; |
| find_if_not |
struct find_if_not_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
constexpr I operator()(I first, S last, Pred pred, Proj proj = {}) const
{
for (; first != last; ++first)
if (!std::invoke(pred, std::invoke(proj, *first)))
return first;
return first;
}
template<ranges::input_range R, class Proj = std::identity,
std::indirect_unary_predicate<
std::projected<ranges::iterator_t<R>, Proj>> Pred>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, Pred pred, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj));
}
};
inline constexpr find_if_not_fn find_if_not; |
Пример
#include <algorithm>
#include <iostream>
#include <iterator>
int main()
{
namespace ranges = std::ranges;
const int n1 = 3;
const int n2 = 5;
const auto v = {4, 1, 3, 2};
if (ranges::find(v, n1) != v.end())
std::cout << "v contains: " << n1 << '\n';
else
std::cout << "v does not contain: " << n1 << '\n';
if (ranges::find(v.begin(), v.end(), n2) != v.end())
std::cout << "v contains: " << n2 << '\n';
else
std::cout << "v does not contain: " << n2 << '\n';
auto is_even = [](int x) { return x % 2 == 0; };
if (auto result = ranges::find_if(v.begin(), v.end(), is_even); result != v.end())
std::cout << "First even element in v: " << *result << '\n';
else
std::cout << "No even elements in v\n";
if (auto result = ranges::find_if_not(v, is_even); result != v.end())
std::cout << "First odd element in v: " << *result << '\n';
else
std::cout << "No odd elements in v\n";
auto divides_13 = [](int x) { return x % 13 == 0; };
if (auto result = ranges::find_if(v, divides_13); result != v.end())
std::cout << "First element divisible by 13 in v: " << *result << '\n';
else
std::cout << "No elements in v are divisible by 13\n";
if (auto result = ranges::find_if_not(v.begin(), v.end(), divides_13);
result != v.end())
std::cout << "First element indivisible by 13 in v: " << *result << '\n';
else
std::cout << "All elements in v are divisible by 13\n";
}Вывод:
v contains: 3 v does not contain: 5 First even element in v: 4 First odd element in v: 1 No elements in v are divisible by 13 First element indivisible by 13 in v: 4
См. также
|
(C++20) |
находит первые два смежных элемента, которые равны (или удовлетворяют заданному предикату) (niebloid) |
|
(C++20) |
находит последнюю последовательность элементов в определенном диапазоне (niebloid) |
|
(C++20) |
ищет любой из набора элементов (niebloid) |
|
(C++20) |
находит первую позицию, где два диапазона различаются (niebloid) |
|
(C++20) |
ищет диапазон элементов (niebloid) |
|
(C++11) |
находит первый элемент, удовлетворяющий определенным критериям (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/ranges/find