В чем разница между 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:: next(и std::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 (если вы не используете отрицательные расстояния).