# std::upper_bound

< cpp‎ | algorithm

定义于头文件 `<algorithm>` |  |
| (1) |
template< class ForwardIt, class T > ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value ); |  | (C++20 前)
template< class ForwardIt, class T > constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value ); |  | (C++20 起)
| (2) |
template< class ForwardIt, class T, class Compare > ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value, Compare comp ); |  | (C++20 前)
template< class ForwardIt, class T, class Compare > constexpr ForwardIt upper_bound( ForwardIt first, ForwardIt last, const T& value, Compare comp ); |  | (C++20 起)

返回指向范围 `[first, last)` 中首个大于 `value` 的元素的迭代器，或若找不到这种元素则返回 `last` 。

范围 `[first, last)` 必须已相对于表达式 !(value < element) 或 !comp(value, element) 划分，即所有令此表达式为 true 的元素必须前趋所有令此表达式为 false 的元素。完全排序的范围满足此判别标准。

第一版本用 operator< 比较元素，第二版本用给定的比较函数 `comp` 。

### 参数

first, last | - | 要检验的元素范围
value | - | 要与元素比较的值
comp | - | 若第一参数小于（即先序于）第二个则返回 ​true 的二元谓词。 谓词函数的签名应等价于如下： bool pred(const Type1 &a, const Type2 &b); 虽然签名不必有 const & ，函数也不能修改传递给它的对象，而且必须接受（可为 const 的）类型 `Type1` 与 `Type2` 的值，无关乎值类别（从而不允许 Type1 & ，亦不允许 Type1 ，除非 `Type1` 的移动等价于复制 (C++11 起)）。 类型 Type1 必须使得 T 类型的对象能隐式转换到 Type1 。类型 Type2 必须使得 ForwardIt 类型的对象能在解引用后隐式转换到 Type2 。 ​
类型要求
- `ForwardIt` 必须满足老式向前迭代器 (LegacyForwardIterator) 的要求。
- `Compare` 必须满足二元谓词 (BinaryPredicate) 的要求。不要求满足 比较 (Compare) 。

### 返回值

指向首个大于 `value` 的元素的迭代器，或若找不到这种元素则为 `last` 。

### 复杂度

进行的比较次数与 `first` 和 `last` 间的距离成对数（至多 log
2(last - first) + O(1) 次比较）。然而，对于非老式随机访问迭代器 (LegacyRandomAccessIterator) ，迭代次自增次数为线性。

### 可能的实现

版本一
    template<class ForwardIt, class T>
    ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value)
    {
        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 (!(value < *it)) {
                first = ++it;
                count -= step + 1;
            }
            else
                count = step;
        }
        return first;
    }
版本二
    template<class ForwardIt, class T, 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;
    }

### 示例

    #include <algorithm>
    #include <iostream>
    #include <vector>

    int main()
    {
        std::vector<int> data = { 1, 2, 4, 5, 5, 6 };

        for (int i = 0; i < 7; ++i) {
            // 搜索首个大于 i 的元素
            auto upper = std::upper_bound(data.begin(), data.end(), i);

            std::cout << i << " < ";
            if (upper != data.end())
                std::cout << *upper << " at index " << std::distance(data.begin(), upper);
            else
                std::cout << "not found";
            std::cout << '\n';
        }
    }

输出：

    0 < 1 at index 0
    1 < 2 at index 1
    2 < 4 at index 2
    3 < 4 at index 2
    4 < 5 at index 3
    5 < 6 at index 5
    6 < not found

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 270 | C++98 | 曾要求 Compare 为严格弱序 | 只需要划分；容许异相比较

### 参阅

equal_range | 返回匹配特定键值的元素范围 (函数模板)
lower_bound | 返回指向第一个不小于给定值的元素的迭代器 (函数模板)
partition | 将范围中的元素分为两组 (函数模板)