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
Definido en el encabezado <algorithm>
Firma de llamada
(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 = { } ) ;
(desde C++20)
(hasta 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 = { } ) ;
(desde 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 = { } ) ;
(desde C++20)
(hasta 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 = { } ) ;
(desde 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) (desde 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) (desde 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) (desde 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) (desde C++20)

Devuelve el primer elemento en el rango [ first , last ) que satisface criterios específicos:

1) find busca un elemento igual a value .
3) find_if busca un elemento para el cual el predicado pred devuelve true .
5) find_if_not busca un elemento para el cual el predicado pred devuelve false .
2,4,6) Igual que (1,3,5) , pero utiliza r como el rango fuente, como si usara ranges:: begin ( r ) como first y ranges:: end ( r ) como last .

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

first, last - el par iterador-centinela que define el rango de elementos a examinar
r - el rango de los elementos a examinar
value - valor con el que comparar los elementos
pred - predicado a aplicar a los elementos proyectados
proj - proyección a aplicar a los elementos

Valor de retorno

Iterador al primer elemento que satisface la condición o iterador igual a last si no se encuentra dicho elemento.

Complejidad

Como máximo last - first aplicaciones del predicado y proyección.

Implementación posible

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)
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;

Notas

Macro de prueba de características Valor Std Característica
__cpp_lib_algorithm_default_value_type 202403 (C++26) Inicialización de lista para algoritmos ( 1,2 )

Ejemplo

#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, "Ana", "dev"},
        {1, "Bob", "devops"},
        {2, "Eve", "ops"}
    };
    const auto who{"Eve"};
    if (auto it = std::ranges::find(folks, who, &folk_info::name); it != folks.end())
        std::cout << std::format("Perfil:\n"
                                 "    UID: {}\n"
                                 "    Nombre: {}\n"
                                 "    Posició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 contiene: " << n1 << '\n';
    else
        std::cout << "v no contiene: " << n1 << '\n';
    if (ranges::find(v.begin(), v.end(), n2) != v.end())
        std::cout << "v contiene: " << n2 << '\n';
    else
        std::cout << "v no contiene: " << 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 << "Primer elemento par en v: " << *result << '\n';
    else
        std::cout << "No hay elementos pares en v\n";
    if (auto result = ranges::find_if_not(v, is_even); result != v.end())
        std::cout << "Primer elemento impar en v: " << *result << '\n';
    else
        std::cout << "No hay elementos impares en 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 << "Primer elemento divisible por 13 en v: " << *result << '\n';
    else
        std::cout << "Ningún elemento en v es divisible por 13\n";
    if (auto result = ranges::find_if_not(v.begin(), v.end(), divides_13);
        result != v.end())
        std::cout << "Primer elemento no divisible por 13 en v: " << *result << '\n';
    else
        std::cout << "Todos los elementos en v son divisibles por 13\n";
    std::vector<std::complex<double>> nums{{4, 2}};
    #ifdef __cpp_lib_algorithm_default_value_type
        // T se deduce en (2) haciendo posible la inicialización de lista
        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());
}

Salida:

Perfil:
    UID: 2
    Nombre: Eve
    Posición: ops
v contiene: 3
v no contiene: 5
Primer elemento par en v: 4
Primer elemento impar en v: 1
Ningún elemento en v es divisible por 13
Primer elemento no divisible por 13 en v: 4

Véase también

encuentra los dos primeros elementos adyacentes que son iguales (o satisfacen un predicado dado)
(objeto función de algoritmo)
encuentra la última secuencia de elementos en un rango determinado
(objeto función de algoritmo)
busca cualquiera de un conjunto de elementos
(objeto función de algoritmo)
encuentra la primera posición donde dos rangos difieren
(objeto función de algoritmo)
busca la primera ocurrencia de un rango de elementos
(objeto función de algoritmo)
encuentra el primer elemento que cumple criterios específicos
(plantilla de función)