请查看std::advance
函数。
根据cppreference,复杂度为:
线性。 但是,如果InputIt额外满足RandomAccessIterator的要求,则复杂性是恒定的。
因此,如果我传递一个迭代器和一个整数,程序如何推断出它是什么迭代器以及如何实现呢?那么该函数有2个重载吗?
答案 0 :(得分:6)
程序如何推导它的迭代器以及如何实现?
它使用std::iterator_traits<T>::iterator_category
确定迭代器类别,然后进行标签分派。
std::iterator_traits
专用于原始指针。原始指针是随机访问迭代器。
例如:
template<class I>
void doadvance(I& i, size_t n, std::random_access_iterator_tag) {
i += n;
}
template<class I, class Tag>
void doadvance(I& i, size_t n, Tag) {
while(n--)
++i;
}
template<class I>
void advance(I& i, size_t n) {
using Tag = typename std::iterator_traits<I>::iterator_category;
doadvance(i, n, Tag{});
}
在C ++ 17中,它可以使用if constexpr
而不是 tag dispatch ,但这会使标准库不向后兼容。这就是为什么它必须继续使用标签分发。
IMO,std::next
比std::advance
具有更好的接口,因为它返回迭代器,因此调用不必占用其自己的代码行。
答案 1 :(得分:6)
程序如何推断出它是什么迭代器
std::iterator_traits
被使用,即将检查std::iterator_traits<It>::iterator_category
,如果它是std::random_access_iterator_tag
,则表示它是RandomAccessIterator。
BTW:std::iterator_traits
专用于原始指针;它们始终是RandomAccessIterator。
该函数有2个重载吗?
std::advance
不再有重载,该实现通常实现几个辅助函数重载,这些重载根据std::advance
中的iterator_category进行调用。