std:: advance
|
Определено в заголовке
<iterator>
|
||
|
template
<
class
InputIt,
class
Distance
>
void advance ( InputIt & it, Distance n ) ; |
(до C++17) | |
|
template
<
class
InputIt,
class
Distance
>
constexpr void advance ( InputIt & it, Distance n ) ; |
(начиная с C++17) | |
Увеличивает данный итератор it на n элементов.
Если
n
отрицательный, итератор декрементируется. В этом случае
InputIt
должен удовлетворять требованиям
LegacyBidirectionalIterator
, иначе поведение не определено.
Содержание |
Параметры
| it | - | итератор для продвижения |
| n | - | количество элементов, на которое it должен быть продвинут |
| Требования к типу | ||
-
InputIt
должен удовлетворять требованиям
LegacyInputIterator
.
|
||
Возвращаемое значение
(нет)
Сложность
Линейный.
Однако, если
InputIt
дополнительно удовлетворяет требованиям
LegacyRandomAccessIterator
, сложность становится постоянной.
Примечания
Поведение не определено, если указанная последовательность инкрементов или декрементов потребует инкрементирования неинкрементируемого итератора (например, конечного итератора) или декрементирования недекрементируемого итератора (например, начального итератора или сингулярного итератора).
Возможная реализация
Смотрите также реализации в libstdc++ и libc++ .
| Версия без constexpr |
|---|
namespace detail { template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::input_iterator_tag) { while (n > 0) { --n; ++it; } } template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::bidirectional_iterator_tag) { while (n > 0) { --n; ++it; } while (n < 0) { ++n; --it; } } template<class It> void do_advance(It& it, typename std::iterator_traits<It>::difference_type n, std::random_access_iterator_tag) { it += n; } } // namespace detail template<class It, class Distance> void advance(It& it, Distance n) { detail::do_advance(it, typename std::iterator_traits<It>::difference_type(n), typename std::iterator_traits<It>::iterator_category()); } |
| Версия с constexpr |
template<class It, class Distance> constexpr void advance(It& it, Distance n) { using category = typename std::iterator_traits<It>::iterator_category; static_assert(std::is_base_of_v<std::input_iterator_tag, category>); auto dist = typename std::iterator_traits<It>::difference_type(n); if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>) it += dist; else { while (dist > 0) { --dist; ++it; } if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, category>) while (dist < 0) { ++dist; --it; } } } |
Пример
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> v{3, 1, 4}; auto vi = v.begin(); std::advance(vi, 2); std::cout << *vi << ' '; vi = v.end(); std::advance(vi, -2); std::cout << *vi << '\n'; }
Вывод:
4 1
Смотрите также
|
(C++11)
|
увеличивает итератор
(шаблон функции) |
|
(C++11)
|
уменьшает итератор
(шаблон функции) |
|
возвращает расстояние между двумя итераторами
(шаблон функции) |
|
|
(C++20)
|
перемещает итератор на заданное расстояние или до заданной границы
(функциональный объект алгоритма) |