Namespaces
Variants

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

Depuis fr.cppreference.net
 
 
Bibliothèque des algorithmes
Algorithmes contraints et algorithmes sur les plages (C++20)
Algorithmes contraints, p.ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modificatrices    
Opérations par lots
(C++17)
Opérations de recherche
Opérations de séquence modificatrices
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Tri et opérations connexes
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations ensemblistes (sur plages triées)
Opérations de fusion (sur plages triées)
Opérations de tas
Opérations de minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Algorithmes contraints
Tous les noms de ce menu appartiennent à l'espace de noms std::ranges
Opérations de séquence non modificatrices
Opérations de séquence modificatrices
Opérations de partitionnement
Opérations de tri
Opérations de recherche binaire (sur plages triées)
       
       
Opérations ensemblistes (sur plages triées)
Opérations de tas
Opérations de minimum/maximum
       
       
Opérations de permutation
Opérations de pliage
Opérations sur le stockage non initialisé
Types de retour
 
Défini dans l'en-tête <algorithm>
Signature d'appel
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) (depuis C++20)
(jusqu'à 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 = {} );
(depuis 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 ranges::borrowed_iterator_t<R>
    find( R&& r, const T& value, Proj proj = {} );
(2) (depuis C++20)
(jusqu'à 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 = {} );
(depuis 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) (depuis 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) (depuis 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) (depuis 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) (depuis C++20)
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*>
I find( Ep&& policy, I first, S last, const T& value, Proj proj = {} );
(7) (depuis 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*>
ranges::borrowed_iterator_t<R>
    find( Ep&& policy, R&& r, const T& value, Proj proj = {} );
(8) (depuis C++26)
template< /*execution-policy*/ Ep,
          std::random_access_iterator I, std::sized_sentinel_for<I> S,
          class Proj = std::identity,
          std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
I find_if( Ep&& policy, I first, S last, Pred pred, Proj proj = {} );
(9) (depuis C++26)
template< /*execution-policy*/ Ep, /*sized-random-access-range*/ R,
          class Proj = std::identity,
          std::indirect_unary_predicate
              <std::projected<ranges::iterator_t<R>, Proj>> Pred >
ranges::borrowed_iterator_t<R>
    find_if( Ep&& policy, R&& r, Pred pred, Proj proj = {} );
(10) (depuis C++26)
template< /*execution-policy*/ Ep,
          std::random_access_iterator I, std::sized_sentinel_for<I> S,
          class Proj = std::identity,
          std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
I find_if_not( Ep&& policy, I first, S last, Pred pred, Proj proj = {} );
(11) (depuis C++26)
template< /*execution-policy*/ Ep, /*sized-random-access-range*/ R,
          class Proj = std::identity,
          std::indirect_unary_predicate
              <std::projected<ranges::iterator_t<R>, Proj>> Pred >
ranges::borrowed_iterator_t<R>
    find_if_not( Ep&& policy, R&& r, Pred pred, Proj proj = {} );
(12) (depuis C++26)

Pour la définition de /*execution-policy*/, voir cette page ; pour la définition de /*sized-random-access-range*/, voir cette page.

Recherche le premier élément (projeté par proj) dans la plage source [firstlast) ou r qui satisfait des critères spécifiques :

1,2) find recherche le premier élément égal à la valeur cible value.
3,4) find_if recherche le premier élément pour lequel le prédicat pred renvoie true.
5,6) find_if_not recherche le premier élément pour lequel le prédicat pred renvoie false.
7-12) Identique à (1-6), mais exécuté selon policy.

Les entités de type fonction décrites sur cette page sont des objets fonctions d'algorithmes (informellement appelés niebloids), c'est-à-dire :

Paramètres

first, last - la paire itérateur-sentinelle définissant la plage source
r - la plage source
value - la valeur cible
pred - le prédicat à appliquer aux éléments (projetés)
proj - la projection à appliquer aux éléments
policy - la politique d'exécution à utiliser

Valeur de retour

Itérateur vers le premier élément satisfaisant la condition, ou last si aucun élément de ce type n'est trouvé.

Complexité

Étant donné N comme ranges::distance(first, last) ou ranges::distance(r):

1,2) Au plus N comparaisons et applications de proj.
3-6) Au plus N applications de pred et proj.
7,8) 𝓞(N) comparaisons et applications de proj.
9-12) 𝓞(N) applications de pred et proj.

Exceptions

7-12) Pendant le processus d'exécution :
  • Si les ressources mémoire temporaires nécessaires à la parallélisation ne sont pas disponibles, std::bad_alloc est levée.
  • Si une exception non attrapée est levée lors de l'accès aux objets via un argument d'algorithme, le comportement est déterminé par la politique d'exécution (pour standard policies, std::terminate est invoquée).

Notes

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_algorithm_default_value_type 202403 (C++26) Initialisation par liste pour les algorithmes ( 1,2 )

Implémentation possible

find
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));
    }
    
    template<ranges::forward_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::next(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));
    }
    
    template<ranges::forward_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::next(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));
    }
    
    template<ranges::forward_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::next(ranges::begin(r), ranges::end(r)),
                       std::ref(pred), std::ref(proj));
    }
};

inline constexpr find_if_not_fn find_if_not;

Exemple

#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("Profile:\n"
                                 "    UID: {}\n"
                                 "    Name: {}\n"
                                 "    Position: {}\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 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";
    
    std::vector<std::complex<double>> nums{{4, 2}};
    #ifdef __cpp_lib_algorithm_default_value_type
        // T gets deduced in (2) making list-initialization possible
        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());
}

Sortie:

Profile:
    UID: 2
    Name: Eve
    Position: ops

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

Voir aussi

trouve le premier élément satisfaisant à des critères spécifiques
(modèle de fonction)
trouve les deux premiers éléments adjacents qui sont égaux (ou satisfont à un prédicat donné)
(objet fonction d'algorithme)
trouve la dernière séquence d'éléments dans un certain intervalle
(objet fonction d'algorithme)
recherche l'un quelconque d'un ensemble d'éléments
(objet fonction d'algorithme)
trouve la première position où deux intervalles diffèrent
(objet fonction d'algorithme)
recherche la première occurrence d'un intervalle d'éléments
(objet fonction d'algorithme)