[英]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.