下面是 lower_bound 和 upper_bound 的源码。

template <typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__val, _Compare __comp) {
    typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType;
 
    _DistanceType __len = std::distance(__first, __last);
 
    while (__len > 0) {
        _DistanceType __half = __len >> 1;
        _ForwardIterator __middle = __first;
        std::advance(__middle, __half);
        if (__comp(__val, __middle))
            __len = __half;
        else {
            __first = __middle;
            ++__first;
            __len = __len - __half - 1;
        }
    }
    return __first;
}
template <typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__val, _Compare __comp) {
    typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType;
 
    _DistanceType __len = std::distance(__first, __last);
 
    while (__len > 0) {
        _DistanceType __half = __len >> 1;
        _ForwardIterator __middle = __first;
        std::advance(__middle, __half);
        if (__comp(__middle, __val)) {
            __first = __middle;
            ++__first;
            __len = __len - __half - 1;
        } else
            __len = __half;
    }
    return __first;
}

我们可以忽略掉相同的类模板,只关注不同的部分:

// upper_bound
_DistanceType __len = std::distance(__first, __last);
while (__len > 0) {
	_DistanceType __half = __len >> 1;
	_ForwardIterator __middle = __first;
	std::advance(__middle, __half);
	if (__comp(__val, __middle))
		__len = __half;
	else {
		__first = __middle;
		++__first;
		__len = __len - __half - 1;
	}
}
// lower_bound
_DistanceType __len = std::distance(__first, __last);
while (__len > 0) {
	_DistanceType __half = __len >> 1;
	_ForwardIterator __middle = __first;
	std::advance(__middle, __half);
	if (__comp(__middle, __val)) {
		__first = __middle;
		++__first;
		__len = __len - __half - 1;
	} else
		__len = __half;
}

首先是计算出区间长度的半(向下取整),如果为零,则说明当前区间长度为1,则返回该值。

否则的话,找到区间中点位置即 __middle = __first + __len ,然后将该值与 __val 对比。

对于 upper_bound:

如果 __val < *__middle 则说明 __middle 及后面的元素均满足 >=__val,缩小右边界 __len = __half.

否则则说明 __middle 及前面的元素均满足 <__val,缩小左边界 __first = __middle;++__first;__len = __len - __half - 1;.

对于 lower_bound:

如果 *__middle < __val 则说明 __middle 及前面的元素均满足 <__val,缩小左边界 __first = __middle;++__first;__len = __len - __half - 1;.

否则则说明 __middle 及后面的元素均满足 >=__val,缩小右边界 __len = __half.

更一般的,对于 lower_bound,如果 __comp() 返回值是 true 则缩小左边界,否则缩小右边界,二分停止的位置为第一个 false 的位置,而 upper_bound 的操作相反。