[英]How is std::advance implemented to change behavior on iterator type?
我们对std::advance
的了解如下:
template <class InputIterator, class Distance>
void advance (InputIterator& i, Distance n);
目的
通过n
元素推进迭代器i
。
如果i
是随机访问迭代器,则该函数使用一次operator+
或operator-
,否则,该函数重复使用增加或减少运算符( operator++
或operator--
),直到n
元素被提前。
我的问题如下:如何实现std::advance
,以便识别it
是否是随机访问迭代器? 它是如何知道它可以使用operator+
而不是operator++
?
通过iterator_traits
和tag dispatch :
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()
不是函数调用; 它是一个构造该类型的临时prvalue的表达式。 然后通过正常的重载分辨率选择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
的重载作为第三个参数接收一个未命名的参数,该参数是其所选标记类型的一个实例。
我想可能会使用std::iterator_traits::iterator_category
来确定std::iterator_traits::iterator_category
的类型。
基于此,它可以决定如何推进事物。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.