В чем разница между std::advance и std::next?

Есть ли что-то еще, кроме заранее взятых отрицательных чисел?

4 ответа

Решение

std::advance

  • изменяет свой аргумент
  • ничего не возвращает
  • работает на входных итераторах или лучше (или двунаправленных итераторах, если задано отрицательное расстояние)

std::next

  • оставляет свой аргумент без изменений
  • возвращает копию аргумента, продвинутую на указанную сумму
  • работает на прямых итераторах или лучше (или двунаправленных итераторах, если дано отрицательное расстояние))

Возможно, самая большая практическая разница в том, что std::next() доступно только в C++11.

std::next() будет продвигаться на один по умолчанию, тогда как std::advance() требует расстояния.

И тогда есть возвращаемые значения:

  • std::advance(): (нет) (переданный итератор изменен)
  • std::next(): N- й преемник.

std::next() принимает отрицательные числа так же, как std::advance и в этом случае требует, чтобы итератор был двунаправленным. std::prev()было бы более читабельным, когда намерение конкретно двигаться назад.

станд:: авансовый

Функция advance() увеличивает позицию итератора, переданного в качестве аргумента. Таким образом, функция позволяет итератору шагать вперед (или назад) более чем на один элемент:

#include <iterator>
void advance (InputIterator& pos, Dist n)
  • Позволяет входному итератору pos step n элементов переместиться вперед (или назад).
  • Для двунаправленных и случайных итераторов n может быть отрицательным шагом назад.
  • Dist - это тип шаблона. Обычно это должен быть целочисленный тип, потому что вызываются такие операции, как<, ++, - и сравнения с 0.
  • Обратите внимание, что advance() не проверяет, пересекает ли он конец () последовательности (он не может проверить, потому что итераторы в общем случае не знают контейнеры, с которыми они работают). Таким образом, вызов этой функции может привести к неопределенному поведению, потому что вызов оператора ++ для конца последовательности не определен.

std:: nextstd::prev новое в C++11)

#include <iterator>
ForwardIterator next (ForwardIterator pos)
ForwardIterator next (ForwardIterator pos, Dist n)
  • Возвращает позицию, которую бы занимал прямой итератор pos, если бы он двигался вперед на 1 или n позиций.
  • Для двунаправленных и случайных итераторов n может быть отрицательным, чтобы привести к предыдущим пропускам.
  • Dist - это тип std::iterator_traits::diff_type.
  • Вызывает заранее (pos,n) для внутреннего временного объекта.
  • Обратите внимание, что next() не проверяет, пересекает ли он конец () последовательности. Таким образом, это до вызывающей стороны, чтобы убедиться, что результат действителен.

цитировать из The C++ Standard Library Second Edition

Они почти одинаковые, за исключением того, что std::next возвращает копию и std::advance изменяет свой аргумент. Обратите внимание, что стандарт требует std::next вести себя как std::advance:

24.4.4 Операции итератора [iterator.operations]

template <class InputIterator, class Distance>
void advance(InputIterator& i [remark: reference], Distance n);

2. Требуется: n должно быть отрицательным только для итераторов с двусторонним и произвольным доступом
3. Эффекты: увеличивает (или уменьшает для отрицательного n) итераторную ссылку i на n.
[...]

template <class ForwardIterator>
ForwardIterator next(ForwardIterator x, [remark: copy]
     typename std::iterator_traits<ForwardIterator>::difference_type n = 1);

6. Эффекты: эквивалентно advance(x, n); return x;

Обратите внимание, что оба фактически поддерживают отрицательные значения, если итератор является входным итератором. Также обратите внимание, что std::next требует, чтобы итератор соответствовал условиям ForwardIterator, в то время как std::advance нужен только Input Iterator (если вы не используете отрицательные расстояния).

Другие вопросы по тегам