Namespaces
Variants

std::ranges:: find, std::ranges:: find_if, std::ranges:: find_if_not

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Определено в заголовке <algorithm>
Сигнатура вызова
(1)
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 = { } ) ;
(начиная с C++20)
(до C++26)
template < std:: input_iterator I, std:: sentinel_for < I > S,

class Proj = std:: identity ,
class T = std :: projected_value_t < I, Proj > >
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 = { } ) ;
(начиная с C++26)
(2)
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 = { } ) ;
(начиная с C++20)
(до C++26)
template < ranges:: input_range R, class Proj = std:: identity ,

class T = std :: projected_value_t < ranges:: iterator_t < R > , Proj > >
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 = { } ) ;
(начиная с C++26)
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) (начиная с 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) (начиная с 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) (начиная с 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) (начиная с 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 применений предиката и проекции.

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

**Примечание:** Весь код C++ внутри тегов `
` и `` оставлен без изменений в соответствии с инструкциями. HTML-разметка и атрибуты также сохранены в оригинальном виде.
Перевод: **Примечание**: В данном случае переводить нечего, так как: 1. HTML-теги и атрибуты остаются без изменений 2. Текст внутри тега ` ` содержит только название функции C++ `find_if_not`, которое не переводится 3. Цифра в скобках `(5)` также не требует перевода
find (1)
struct find_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S,
             class Proj = std::identity,
             class T = std::projected_value_t<I, Proj>>
    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 (3)
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 (5)
find_if_not (5)
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;

Примечания

Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_lib_algorithm_default_value_type 202403 (C++26) Списковая инициализация для алгоритмов ( 1,2 )

Пример

#include <algorithm>
#include <cassert>
#include <complex>
#include <format>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
void projector_example()
{
    struct folk_info
    {
        unsigned uid;
        std::string name, position;
    };
    std::vector<folk_info> folks
    {
        {0, "Ана", "dev"},
        {1, "Боб", "devops"},
        {2, "Ева", "операции"}
    };
    const auto who{"Ева"};
    if (auto it = std::ranges::find(folks, who, &folk_info::имя); it != folks.end())
        std::cout << std::format("Профиль:\n"
                                 "    UID: {}\n"
                                 "    Имя: {}\n"
                                 "    Позиция: {}\n\n",
                                 it->uid, it->name, it->position);
}
int main()
{
    namespace ranges = std::ranges;
    projector_example();
    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 содержит: " << n1 << '\n';
    else
        std::cout << "v не содержит: " << n1 << '\n';
    if (ranges::find(v.begin(), v.end(), n2) != v.end())
        std::cout << "v содержит: " << n2 << '\n';
    else
        std::cout << "v не содержит: " << 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 << "Первый четный элемент в v: " << *result << '\n';
    else
        std::cout << "В векторе нет четных элементов\n";
    if (auto result = ranges::find_if_not(v, is_even); result != v.end())
        std::cout << "Первый нечетный элемент в v: " << *result << '\n';
    else
        std::cout << "В векторе нет нечетных элементов\n";
    auto divides_13 = [](int x) { return x % 13 == 0; };
    if (auto result = ranges::find_if(v, divides_13); result != v.end())
        std::cout << "Первый элемент, делящийся на 13 в v: " << *result << '\n';
    else
        std::cout << "Ни один элемент в v не делится на 13\n";
    if (auto result = ranges::find_if_not(v.begin(), v.end(), divides_13);
        result != v.end())
        std::cout << "Первый элемент, не делящийся на 13 в v: " << *result << '\n';
    else
        std::cout << "Все элементы в v делятся на 13\n";
    std::vector<std::complex<double>> nums{{4, 2}};
    #ifdef __cpp_lib_algorithm_default_value_type
        // T выводится в (2), делая возможной инициализацию списком
        const auto it = ranges::find(nums, {4, 2});
    #else
        const auto it = ranges::find(nums, std::complex<double>{4, 2});
    #endif
    assert(it == nums.begin());
}

Вывод:

Профиль:
    UID: 2
    Имя: Eve
    Должность: ops
v содержит: 3
v не содержит: 5
Первый четный элемент в v: 4
Первый нечетный элемент в v: 1
Ни один элемент в v не делится на 13
Первый элемент не делящийся на 13 в v: 4

Смотрите также

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