Namespaces
Variants

std::upper_bound

De fr.cppreference.net
 
 
Bibliothèque d'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)

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

Opérations de tri
Opérations de recherche binaire
(sur plages partitionnées)
Opérations d'ensemble (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


 
Défini dans l'en-tête <algorithm>
template< class ForwardIt, class T >
ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                       const T& value );
(1) (jusqu'à C++26)
(constexpr depuis C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type >
constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                                 const T& value );
(depuis C++26)
template< class ForwardIt, class T, class Compare >
ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                       const T& value, Compare comp );
(2) (jusqu'à C++26)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type,
          class Compare >
constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last,
                                 const T& value, Compare comp );
(depuis C++26)

Recherche le premier élément dans la plage partitionnée [firstlast) qui est ordonné après value.

1) L'ordre est déterminé par operator<:

Renvoie le premier itérateur iter dans [firstlast)bool(value < *iter) est true, ou last si un tel iter n'existe pas.

Si les éléments elem de [firstlast) ne sont pas partitionnés par rapport à l'expression bool(value < elem), le comportement est indéfini.

(jusqu'à C++20)

Équivalent à std::upper_bound(first, last, value, std::less{}).

(depuis C++20)
2) L'ordre est déterminé par comp:
Renvoie le premier itérateur iter dans [firstlast)bool(comp(value, *iter)) est true, ou last si un tel iter n'existe pas.
Si les éléments elem de [firstlast) ne sont pas partitionnés par rapport à l'expression bool(comp(value, elem)), le comportement est indéfini.

Paramètres

first, last - la paire d'itérateurs définissant la plage partitionnée des éléments à examiner
value - valeur à comparer aux éléments
comp - prédicat binaire qui renvoie ​ true si le premier argument est ordonné avant le second.

La signature de la fonction de prédicat doit être équivalente à ce qui suit :

bool pred ( const Type1 & a, const Type2 & b ) ;

Bien que la signature n'ait pas besoin d'avoir const & , la fonction ne doit pas modifier les objets qui lui sont passés et doit pouvoir accepter toutes les valeurs de type (éventuellement const) Type1 et Type2 indépendamment de la catégorie de valeur (ainsi, Type1 & n'est pas autorisé , pas plus que Type1 sauf si pour Type1 un déplacement équivaut à une copie (depuis C++11) ).
Le type Type1 doit être tel qu'un objet de type T puisse être implicitement converti en Type1 . Le type Type2 doit être tel qu'un objet de type ForwardIt puisse être déréférencé puis implicitement converti en Type2 . ​

Exigences de type
-
ForwardIt doit satisfaire aux exigences de LegacyForwardIterator .
-
Compare doit satisfaire aux exigences de BinaryPredicate . Il n'est pas requis de satisfaire Compare .

Valeur de retour

Itérateur vers le premier élément de la plage [ first , last ) ordonné après value , ou last si aucun élément n'est trouvé.

Complexité

Étant donné N comme std:: distance ( first, last ) :

1) Au plus log 2 (N)+O(1) comparaisons avec value en utilisant operator < (jusqu'en C++20) std:: less { } (depuis C++20) .
2) Au plus log 2 (N)+O(1) applications du comparateur comp .

Cependant, si ForwardIt n'est pas un LegacyRandomAccessIterator , le nombre d'incrémentations d'itérateur est linéaire en N . Notamment, les itérateurs de std::map , std::multimap , std::set , et std::multiset ne sont pas à accès aléatoire, et donc leurs fonctions membres upper_bound devraient être préférées.

Implémentation possible

Voir également les implémentations dans libstdc++ et libc++ .

upper_bound (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value)
{
    return std::upper_bound(first, last, value, std::less{});
}
upper_bound (2)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type,
         class Compare>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value, Compare comp)
{
    ForwardIt it;
    typename std::iterator_traits<ForwardIt>::difference_type count, step;
    count = std::distance(first, last);
    while (count > 0)
    {
        it = first; 
        step = count / 2;
        std::advance(it, step);
        if (!comp(value, *it))
        {
            first = ++it;
            count -= step + 1;
        } 
        else
            count = step;
    }
    return first;
}

Notes

Bien que std::upper_bound exige seulement que [ first , last ) soit partitionné, cet algorithme est généralement utilisé dans le cas où [ first , last ) est trié, de sorte que la recherche binaire soit valide pour toute value .

Pour tout itérateur iter dans [ first , last ) , std::upper_bound requiert que value < * iter et comp ( value, * iter ) soient bien formés, tandis que std::lower_bound requiert que * iter < value et comp ( * iter, value ) soient bien formés à la place.

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 )

Exemple

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <vector>
struct PriceInfo { double price; };
int main()
{
    const std::vector<int> data{1, 2, 4, 5, 5, 6};
    for (int i = 0; i < 7; ++i)
    {
        // Rechercher le premier élément supérieur à i
        auto upper = std::upper_bound(data.begin(), data.end(), i);
        std::cout << i << " < ";
        upper != data.end()
            ? std::cout << *upper << " à l'indice " << std::distance(data.begin(), upper)
            : std::cout << "non trouvé";
        std::cout << '\n';
    }
    std::vector<PriceInfo> prices{{100.0}, {101.5}, {102.5}, {102.5}, {107.3}};
    for (double to_find : {102.5, 110.2})
    {
        auto prc_info = std::upper_bound(prices.begin(), prices.end(), to_find,
            [](double value, const PriceInfo& info)
            {
                return value < info.price;
            });
        prc_info != prices.end()
            ? std::cout << prc_info->price << " à l'indice " << prc_info - prices.begin()
            : std::cout << to_find << " non trouvé";
        std::cout << '\n';
    }
    using CD = std::complex<double>;
    std::vector<CD> nums{{1, 0}, {2, 2}, {2, 1}, {3, 0}, {3, 1}};
    auto cmpz = [](CD x, CD y) { return x.real() < y.real(); };
    #ifdef __cpp_lib_algorithm_default_value_type
        auto it = std::upper_bound(nums.cbegin(), nums.cend(), {2, 0}, cmpz);
    #else
        auto it = std::upper_bound(nums.cbegin(), nums.cend(), CD{2, 0}, cmpz);
    #endif
    assert((*it == CD{3, 0}));
}

Sortie :

0 < 1 à l'indice 0
1 < 2 à l'indice 1
2 < 4 à l'indice 2
3 < 4 à l'indice 2
4 < 5 à l'indice 3
5 < 6 à l'indice 5
6 < non trouvé 
107.3 à l'indice 4
110.2 non trouvé

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement tel que publié Comportement corrigé
LWG 270 C++98 Compare devait satisfaire Compare et T devait être
LessThanComparable (ordre faible strict requis)
seul un partitionnement est requis ;
comparaisons hétérogènes autorisées
LWG 384 C++98 au maximum log 2 (N)+1 comparaisons étaient autorisées corrigé en log 2 (N)+O(1)
LWG 577 C++98 last ne pouvait pas être retourné autorisé
LWG 2150 C++98 si un itérateur iter existe dans [ first , last ) tel que
bool ( comp ( value, * iter ) ) est true , std::upper_bound
pouvait retourner n'importe quel itérateur dans [ iter , last )
aucun itérateur après
iter ne peut être retourné

Voir aussi

trouve la plage d'éléments correspondant à la valeur donnée en utilisant la recherche binaire
(modèle de fonction & objet fonction d'algorithme)
trouve le premier élément non inférieur à la valeur donnée en utilisant la recherche binaire
(modèle de fonction & objet fonction d'algorithme)
divise une plage d'éléments en deux groupes
(modèle de fonction & objet fonction d'algorithme)
localise le point de partition d'une plage partitionnée
(modèle de fonction & objet fonction d'algorithme)
trouve le premier élément supérieur à la valeur donnée en utilisant la recherche binaire
(objet fonction d'algorithme)
retourne un itérateur vers le premier élément supérieur à la clé donnée
(fonction membre publique de std::set<Key,Compare,Allocator>)
retourne un itérateur vers le premier élément supérieur à la clé donnée
(fonction membre publique de std::multiset<Key,Compare,Allocator>)