Espacios de nombres
Variantes

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

De cppreference.com
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Algoritmos restringidos
Operaciones de secuencia no modificantes
Operaciones de secuencia modificantes
Operaciones en almacenamiento sin inicializar
Operaciones de partición
Operaciones de ordenamiento
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de montículo/montón
Operaciones de mínimo/máximo
Permutaciones
 
<tbody> </tbody>
Definido en el archivo de encabezado <algorithm>
Signatura de la llamada
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) (desde 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) (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( 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 que el predicado pred devuelve true.
5) find_if_not busca un elemento para el que el predicado pred devuelve false.
2,4,6) Igual que (1,3,5), pero usa 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 niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Parámetros

first, last - El rango de los 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 cumple la condición o un iterador igual a last si no se encuentra dicho elemento.

Complejidad

A lo sumo last - first aplicaciones del predicado y la proyección.

Posible implementación

Primera versión
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;
Segunda versión
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;
Tercera versión
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;

Ejemplo

#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 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 es_par = [](int x) { return x % 2 == 0; };

    if (auto resultado = ranges::find_if(v.begin(), v.end(), es_par);
        resultado != v.end()) {
      std::cout << "Primer elemento par en v: " << *resultado << '\n';
    } else {
      std::cout << "No hay elementos pares en v\n";
    }

    if (auto resultado = ranges::find_if_not(v, es_par); resultado != v.end()) {
      std::cout << "Primer elemento non en v: " << *resultado << '\n';
    } else {
      std::cout << "No hay elementos nones en v\n";
    }

    auto se_divide_por_13 = [](int x) { return x % 13 == 0; };

    if (auto resultado = ranges::find_if(v, se_divide_por_13);
        resultado != v.end()) {
      std::cout << "Primer elemento divisible por 13 en v: " << *resultado << '\n';
    } else {
      std::cout << "No hay elementos en v divisibles por 13\n";
    }

    if (auto resultado = ranges::find_if_not(v.begin(), v.end(), se_divide_por_13);
        resultado != v.end()) {
      std::cout << "Primer elemento no divisible por 13 en v: " << *resultado << '\n';
    } else {
      std::cout << "Todos los elementos en v son divisibles por 13\n";
    }
}

Salida:

v contiene: 3
v no contiene: 5
Primer elemento par en v: 4
Primer elemento non en v: 1
No hay elementos en v divisibles por 13
Primer elemento no divisible por 13 en v: 4

Véase también

Encuentra dos primeros elementos contiguos idénticos (o que satisfagan un predicado dado).
(niebloid) [editar]
Encuentra la última secuencia de elementos en un cierto rango.
(niebloid) [editar]
Busca por cualquiera de un conjunto de elementos.
(niebloid) [editar]
Encuentra la primera posición donde dos rangos difieren.
(niebloid) [editar]
Busca una subsecuencia de elementos en un rango.
(niebloid) [editar]
Encuentra el primer elemento que satisfaga un criterio específico.
(plantilla de función) [editar]