通过iterator_traits
和标记调度:
template<class InputIterator, class Distance>
void advance_impl(InputIterator& i, Distance n, std::random_access_iterator_tag) {
i += n;
}
template<class InputIterator, class Distance>
void advance_impl(InputIterator& i, Distance n, std::bidirectional_iterator_tag) {
if (n < 0) {
while (n++) --i;
} else {
while (n--) ++i;
}
}
template<class InputIterator, class Distance>
void advance_impl(InputIterator& i, Distance n, std::input_iterator_tag) {
assert(n >= 0);
while (n--) ++i;
}
template<class InputIterator, class Distance>
void advance (InputIterator& i, Distance n) {
advance_impl(i, n,
typename std::iterator_traits<InputIterator>::iterator_category());
}
请注意,这iterator_category
是一种类型(std::input_iterator_tag
等),因此iterator_category()
不是函数调用;它是一个构造该类型的临时纯右值的表达式。advance_impl
然后通过正常的重载决议选择适当的重载。这称为标签调度。等效地可以写:
template<class InputIterator, class Distance>
void advance (InputIterator& i, Distance n) {
typename std::iterator_traits<InputIterator>::iterator_category the_tag;
advance_impl(i, n, the_tag);
}
的重载advance_impl
作为它们的第三个参数接收一个未命名的参数,该参数是它们选择的标记类型的一个实例。