![](/img/trans.png)
[英]How is std::advance implemented to change behavior on iterator type?
[英]How std::advance iterator type is deduced?
请看一下std::advance
函数。 根据cppreference,复杂性是:
线性。 但是,如果InputIt另外满足RandomAccessIterator的要求,则复杂性是不变的。
因此,如果我传递一个迭代器和一个整数,程序如何推导它是什么迭代器以及它是如何实现的? 那么这个功能有2个重载或者是什么?
程序如何推导出迭代器及其实现方式?
它使用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
,但这会使标准库不向后兼容。 这就是为什么它必须继续使用标签调度 。
IMO, std::next
有一个比std::advance
更好的接口,因为它返回迭代器,因此调用不必占用自己的代码行。
程序如何推导它是什么迭代器
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调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.