std::advance(3)
π NAME π
std::advance β the NAME line is literally std::advance - std::advance, and this is the C++ Standard Libary manual page for std::advance(3), bestie. We're doing iterator math, and it's honestly giving main-character energy. π
πΈ Synopsis πΈ
Defined in header <iterator>:
template< class InputIt, class Distance > (until C++17)
void advance( InputIt& it, Distance n );
template< class InputIt, class Distance > (since C++17)
constexpr void advance( InputIt& it, Distance n );
Increments given iterator it by n elements. β¨
If n is negative, the iterator is decremented. In this case, InputIt must meet the requirements of LegacyBidirectionalIterator, otherwise the behavior is undefined. No cap, that part matters. π«Ά
π Parameters π
itβ iterator to be advancednβ number of elementsitshould be advanced
π¦ Type requirements π¦
InputItmust meet the requirements ofLegacyInputIterator.
β¨ Return value β¨
(none) β literally nothing, bestie. π
π₯ Complexity π₯
Linear.
However, if InputIt additionally meets the requirements of LegacyRandomAccessIterator, complexity is constant. Slay. β
π Notes π
The behavior is undefined if the specified sequence of increments or decrements would require that a non-incrementable iterator (such as the past-the-end iterator) is incremented, or that a non-decrementable iterator (such as the front iterator or the singular iterator) is decremented. π This is the βdo not do thatβ zone.
π§ Possible implementation π§
See also the implementations in libstdc++ and libc++.
π Non-constexpr version π
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 version π
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;
}
}
}
π Example π
// Run this code
#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';
}
π Output π
4 1
π See also π
nextβ increment an iterator(C++11)(function template)prevβ decrement an iterator(C++11)(function template)distanceβ returns the distance between two iterators (function template)ranges::advanceβ advances an iterator by given distance or to a given bound(C++20)(niebloid)
Thatβs the whole vibe check, bestie: from http://cppreference.com, dated 2024.06.10, and yes the page is std::advance(3). πβ¨π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms