Namespaces
Variants

std::ranges::contains, std::ranges::contains_subrange

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p.ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenación y relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenación
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjunto (en rangos ordenados)
Operaciones de fusión (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de particionado
Operaciones de ordenación
Operaciones de búsqueda binaria (en rangos ordenados)
       
       
Operaciones de conjunto (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
Definido en el encabezado <algorithm>
Firma de 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 bool contains( I first, S last, const T& value, Proj proj = {} );
(1) (desde C++23)
(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 bool contains( I first, S last, const T& value, Proj proj = {} );
(desde C++26)
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 bool contains( R&& r, const T& value, Proj proj = {} );
(2) (desde C++23)
(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 bool contains( R&& r, const T& value, Proj proj = {} );
(desde C++26)
template< std::forward_iterator I1, std::sentinel_for<I1> S1,
          std::forward_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 contains_subrange( I1 first1, S1 last1, I2 first2, S2 last2,
                                  Pred pred = {},
                                  Proj1 proj1 = {}, Proj2 proj2 = {} );
(3) (desde C++23)
template< ranges::forward_range R1, ranges::forward_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 contains_subrange( R1&& r1, R2&& r2, Pred pred = {},
                                  Proj1 proj1 = {}, Proj2 proj2 = {} );
(4) (desde C++23)
template< /*execution-policy*/ Ep,
          std::random_access_iterator I, std::sized_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*>
bool contains( Ep&& policy, I first, S last, const T& value, Proj proj = {} );
(5) (desde C++26)
template< /*execution-policy*/ Ep, /*sized-random-access-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*>
bool contains( Ep&& policy, R&& r, const T& value, Proj proj = {} );
(6) (desde C++26)
template< /*execution-policy*/ Ep,
          std::random_access_iterator I1, std::sized_sentinel_for<I1> S1,
          std::random_access_iterator I2, std::sized_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>
bool contains_subrange( Ep&& policy, I1 first1, S1 last1, I2 first2, S2 last2,
                        Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
(7) (desde C++26)
template< /*execution-policy*/ Ep,
          /*sized-random-access-range*/ R1, /*sized-random-access-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>
bool contains_subrange( Ep&& policy, R1&& r1, R2&& r2, Pred pred = {},
                        Proj1 proj1 = {}, Proj2 proj2 = {} );
(8) (desde C++26)

Para la definición de /*execution-policy*/, véase esta página; para la definición de /*sized-random-access-range*/, véase esta página.

1,2) Comprueba si el rango de origen contiene o no el valor objetivo value.
1) El rango de origen es [first, last).
2) El rango de origen es r.
3,4) Comprueba si el rango objetivo es o no un subrango del rango de origen.
3) El rango de origen es [first1, last1), y el rango objetivo es [first2, last2).
4) El rango de origen es r1, y el rango objetivo es r2.
5-8) Igual que (1-4), pero ejecutado según policy.

Las entidades similares a funciones descritas en esta página son objetos función de algoritmo (conocidos informalmente como niebloids), es decir:

Parámetros

first/first1, last/last1 - el par iterador-centinela que define el rango
de origen first2, last2 - el par iterador-centinela que define el rango
objetivo r/r1 - el rango de origen
value - el valor objetivo
r2 - el rango objetivo
pred/pred1 - el predicado a aplicar a los elementos (proyectados) en el rango de origen
pred2 - el predicado a aplicar a los elementos (proyectados) en el rango objetivo
proj/proj1 - la proyección a aplicar a los elementos en el rango de origen
proj2 - la proyección a aplicar a los elementos en el rango objetivo
policy - la política de ejecución a usar

Valor de retorno

1) ranges::find(std::move(first), last, value, proj) != last
2) ranges::find(r, value, proj) != ranges::end(r)
3) first2 == last2 || !ranges::search(first1, last1, first2, last2, pred, proj1, proj2).empty()
4) ranges::empty(r2) || !ranges::search(r1, r2, pred, proj1, proj2).empty()
5-8) Igual que (1-4), pero inserta std::forward<Ep>(policy) en la lista de argumentos de ranges::find o ranges::search como primer argumento.

Complejidad

Dado

  • N como ranges::distance(first, last) o ranges::distance(r),
  • N1 como ranges::distance(first1, last1) o ranges::distance(r1), y
  • N2 como ranges::distance(first2, last2) o ranges::distance(r2):
1,2) Como máximo N comparaciones y aplicaciones de proj.
3,4) Como máximo N1·N2 aplicaciones de pred y proj.
5,6) 𝓞(N) comparaciones y aplicaciones de proj.
7,8) 𝓞(N1·N2) aplicaciones de pred y proj.

Excepciones

5-8) Durante el proceso de ejecución:
  • Si los recursos de memoria temporales requeridos para la paralelización no están disponibles, se lanza std::bad_alloc.
  • Si se lanza una excepción no capturada mientras se accede a objetos a través de un argumento del algoritmo, el comportamiento está determinado por la política de ejecución (para políticas estándar, se invoca std::terminate).

Notas

En C++20, se puede implementar contains con ranges::find(haystack, needle) != ranges::end(haystack) o contains_subrange con !ranges::search(haystack, needle).empty().

ranges::contains_subrange, al igual que ranges::search, y a diferencia de std::search, no tiene soporte para buscadores (como std::boyer_moore_searcher).

Macro de prueba de características Valor Estándar Característica
__cpp_lib_ranges_contains 202207L (C++23) ranges::contains y ranges::contains_subrange
__cpp_lib_algorithm_default_value_type 202403L (C++26) Inicialización con lista para algoritmos (1,2)

Posible implementación

contains (1,2)
struct contains_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 bool operator()(I first, S last, const T& value, Proj proj = {}) const
    {
        return ranges::find(std::move(first), last, value, proj) != last;
    }
    
    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 bool operator()(R&& r, const T& value, Proj proj = {}) const
    {
        return ranges::find(r, value, proj) != ranges::end(r);
    }
};

inline constexpr contains_fn contains{};
contains_subrange (3,4)
struct contains_subrange_fn
{
    template<std::forward_iterator I1, std::sentinel_for<I1> S1,
             std::forward_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
    {
        return (first2 == last2) ||
                   !ranges::search(first1, last1, first2, last2,
                                   pred, proj1, proj2).empty();
    }
    
    template<ranges::forward_range R1, ranges::forward_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 ranges::empty(r2) ||
                   !ranges::search(r1, r2, pred, proj1, proj2).empty();
    }
};

inline constexpr contains_subrange_fn contains_subrange{};

Ejemplo

#include <algorithm>
#include <array>
#include <complex>

namespace ranges = std::ranges;

int main()
{
    constexpr auto haystack = std::array{3, 1, 4, 1, 5};
    constexpr auto needle = std::array{1, 4, 1};
    constexpr auto bodkin = std::array{2, 5, 2};
    
    static_assert
    (
        ranges::contains(haystack, 4) &&
       !ranges::contains(haystack, 6) &&
        ranges::contains_subrange(haystack, needle) &&
       !ranges::contains_subrange(haystack, bodkin)
    );
    
    constexpr std::array<std::complex<double>, 3> nums{{{1, 2}, {3, 4}, {5, 6}}};
    #ifdef __cpp_lib_algorithm_default_value_type
        static_assert(ranges::contains(nums, {3, 4}));
    #else
        static_assert(ranges::contains(nums, std::complex<double>{3, 4}));
    #endif
}

Ver también

encuentra el primer elemento que satisface criterios específicos
(objeto función de algoritmo)
busca la primera aparición de un rango de elementos
(objeto función de algoritmo)
determina si un elemento existe en un rango mediante búsqueda binaria
(objeto función de algoritmo)
determina si una secuencia es una subsecuencia de otra
(objeto función de algoritmo)
comprueba si un predicado es true para todos, alguno o ninguno de los elementos en un rango
(objeto función de algoritmo)