为什么std::binary_search使用ForwardIterator而不是RandomIterator ?
Why does std::binary_search use ForwardIterator, not RandomIterator?
我很惊讶,当它使用不支持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()
,并在适合实现的情况下为不同的迭代器使用其他技术)。请记住,Bidirectional
和RandomAccess
迭代器是ForwardIterator
的特化。