为什么std::binary_search使用ForwardIterator而不是RandomIterator ?

Why does std::binary_search use ForwardIterator, not RandomIterator?

本文关键字:RandomIterator ForwardIterator 使用 std binary search 为什么      更新时间:2023-10-16

我很惊讶,当它使用不支持auto middle = first + (last - first) / 2;的ForwardIterator时,如何计算middle

当然,即使它不是随机迭代器,您也可以计算元素的数量。

如果它是一个随机迭代器,你可以通过last - first在常数时间内得到它,如果不是,你至少可以将first逐个推进到last,并以线性复杂度得到计数。

应该实现的是根据迭代器标签进行分派,下面是std::advance的实现图示例,展示了如何根据迭代器的类型进行分派:

template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n,
input_iterator_tag)
{
    while (n--) ++i;
}
template <class ForwardIterator, class Distance>
inline void __advance(ForwardIterator& i, Distance n,
forward_iterator_tag)
{
    advance(i, n, input_iterator_tag());
}
template <class BidiectionalIterator, class Distance>
inline void __advance(BidiectionalIterator& i, Distance n,
bidirectional_iterator_tag)
{
    if (n >= 0)
        while (n--) ++i;
    else
        while (n++) --i;
}
template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n,
random_access_iterator_tag)
{
    i += n;
}
template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n)
{
    __advance(i, n, iterator_traits<InputIterator>::iterator_category());
}

std::binary_search()的行为在概念上等同于(对于非比较器版本)

template <class ForwardIterator, class T>
  bool binary_search (ForwardIterator first, ForwardIterator last, const T& val)
{
  first = std::lower_bound(first,last,val);
  return (first!=last && !(val<*first));
}

,其中std::lower_bound()可以根据需要专门用于不同的迭代器(例如,为ForwardIterator使用std::distance()std::advance(),并在适合实现的情况下为不同的迭代器使用其他技术)。请记住,BidirectionalRandomAccess迭代器是ForwardIterator的特化。