简体   繁体   English

如何推导出std :: advance迭代器类型?

[英]How std::advance iterator type is deduced?

Please take a look at the std::advance function. 请看一下std::advance函数。 According to cppreference the complexity is: 根据cppreference,复杂性是:

Linear. 线性。 However, if InputIt additionally meets the requirements of RandomAccessIterator, complexity is constant. 但是,如果InputIt另外满足RandomAccessIterator的要求,则复杂性是不变的。

So if I pass an iterator and an integer, how does the program deduce what iterator it is and how it is implemented? 因此,如果我传递一个迭代器和一个整数,程序如何推导它是什么迭代器以及它是如何实现的? So are there 2 overloads for the function or what? 那么这个功能有2个重载或者是什么?

how program deduce what iterator it and how it is implemented? 程序如何推导出迭代器及其实现方式?

It uses std::iterator_traits<T>::iterator_category to determine iterator category and then does tag dispatching . 它使用std::iterator_traits<T>::iterator_category来确定迭代器类别,然后执行标记调度

std::iterator_traits is specialised for raw pointers. std::iterator_traits专门用于原始指针。 Raw pointers are random-access iterators. 原始指针是随机访问迭代器。

Eg: 例如:

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{});
}

In C++17 instead of tag dispatching it can use if constexpr , but that would make the standard library not backward compatible. 在C ++ 17而不是标签调度中,它可以使用if constexpr ,但这会使标准库不向后兼容。 This is why it has to keep using tag dispatching . 这就是为什么它必须继续使用标签调度

IMO, std::next has a better interface than std::advance because it returns the iterator, so that the invocation does not have to occupy its own line of code. IMO, std::next有一个比std::advance更好的接口,因为它返回迭代器,因此调用不必占用自己的代码行。

how program deduce what iterator it is 程序如何推导它是什么迭代器

std::iterator_traits is used, ie std::iterator_traits<It>::iterator_category will be checked, and if it's std::random_access_iterator_tag , means it's a RandomAccessIterator. std::iterator_traits被使用,即std::iterator_traits<It>::iterator_category将被检查,并且如果它是std::random_access_iterator_tag ,意味着它是一个RandomAccessIterator的。

BTW: std::iterator_traits is specialized for raw pointers; BTW: std::iterator_traits专门用于原始指针; they're always RandomAccessIterator. 他们总是RandomAccessIterator。

So are there 2 overloads for the function or what? 那么这个功能有2个重载或者是什么?

There're no more overloads of std::advance , the implementation usually implements several helper function overloads, which are called according to the iterator_category in std::advance . std::advance不再有重载,实现通常会实现几个辅助函数重载,这些重载根据std::advance的iterator_category调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何实现std :: advance来改变迭代器类型的行为? - How is std::advance implemented to change behavior on iterator type? 如何使用 lambda 在 std::function 参数中推导出模板类型? - How to have template type deduced in std::function arguments with lambda? 如何将 std::pair 迭代器传递给函数模板并推导出迭代器类型? - How to pass a std::pair of iterators to a function template and have the iterator types deduced? 推进std :: vector std :: advance VS运算符+的迭代器? - Advance iterator for the std::vector std::advance VS operator +? 为什么std :: advance不返回生成的迭代器? - Why does not std::advance return the resulting iterator? std :: multiset的迭代器上的std :: advance是否在恒定时间内完成? - Is std::advance on an iterator of std::multiset done in constant time? 如何推导出std :: move模板参数? - How are std::move template parameters deduced? 负数导致std :: multimap end()迭代器的std :: advance崩溃 - std::advance of std::multimap end() iterator by negative number crashes 为什么std :: function不能接受推导类型作为模板参数? - Why can std::function not accept a deduced type as its template parameter? 如何从自动退货类型中推断出类型? - How is type deduced from auto return type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM