簡體   English   中英

如何實現std :: advance來改變迭代器類型的行為?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM