std::ranges::next(3)
β¨ std::ranges::next(3) β C++ Standard Libary β¨
π NAME π
std::ranges::next β std::ranges::next, bestie. Thatβs literally the name, and itβs iconic.
π¦ SYNOPSIS π¦
Okay so first things first: this lives in the header <iterator>, and the call signatures are giving very much βfour flavors of the same cutie.β Here they are, exactly:
Defined in header <iterator>
Call signature
template< std::input_or_output_iterator I >
(1) (since C++20)
constexpr I next( I i );
template< std::input_or_output_iterator I >
(2) (since C++20)
constexpr I next( I i, std::iter_difference_t<I> n );
template< std::input_or_output_iterator I, std::sentinel_for<I> S
>
(3) (since C++20)
constexpr I next( I i, S bound );
template< std::input_or_output_iterator I, std::sentinel_for<I> S
>
(4) (since C++20)
constexpr I next( I i, std::iter_difference_t<I> n, S bound );
The whole vibe: return the n^th successor of iterator i. Slay.
The function-like entities described on this page are niebloids, that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
In practice, they may be implemented as function objects, or with special compiler extensions. No cap.
πΈ PARAMETERS πΈ
iβ an iteratornβ number of elements to advanceboundβ sentinel denoting the end of the rangeipoints to
π RETURN VALUE π
- The successor of iterator
i. - The
n^th successor of iteratori. - The first iterator equivalent to
bound. - The
n^th successor of iteratori, or the first iterator equivalent tobound, whichever is first.
π₯ COMPLEXITY π₯
- Constant.
- Constant if
Imodelsstd::random_access_iterator; otherwise linear. - Constant if
IandSmodels bothstd::random_access_iterator<I>andstd::sized_sentinel_for<S, I>, or ifIandSmodelsstd::assignable_from<I&, S>; otherwise linear. - Constant if
IandSmodels bothstd::random_access_iterator<I>andstd::sized_sentinel_for<S, I>; otherwise linear.
π§ POSSIBLE IMPLEMENTATION π§
Hereβs the little possible-implementation moment, preserved with love and zero edits to the facts:
struct next_fn
{
template<std::input_or_output_iterator I>
constexpr I operator()(I i) const
{
++i;
return i;
}
template<std::input_or_output_iterator I>
constexpr I operator()(I i, std::iter_difference_t<I> n) const
{
ranges::advance(i, n);
return i;
}
template<std::input_or_output_iterator I, std::sentinel_for<I> S>
constexpr I operator()(I i, S bound) const
{
ranges::advance(i, bound);
return i;
}
template<std::input_or_output_iterator I, std::sentinel_for<I> S>
constexpr I operator()(I i, std::iter_difference_t<I> n, S bound) const
{
ranges::advance(i, n, bound);
return i;
}
};
inline constexpr auto next = next_fn();
π«Ά NOTES π«Ά
Okay bestie, this is the part where the lore gets real. Although the expression ++x.begin() often compiles, it is not guaranteed to do so: x.begin() is an rvalue expression, and there is no requirement that specifies that increment of an rvalue is guaranteed to work. In particular, when iterators are implemented as pointers or its operator++ is lvalue-ref-qualified, ++x.begin() does not compile, while ranges::next(x.begin()) does. So yeah β this is not me being dramatic, this is the actual rule. π
Lowkey important: ++x.begin() compiling is not a promise. Do not treat βoften compilesβ as βalways valid,β bestie.
π EXAMPLE π
// Run this code
#include <cassert>
#include <iterator>
int main()
{
auto v = {3, 1, 4};
{
auto n = std::ranges::next(v.begin());
assert(*n == 1);
}
{
auto n = std::ranges::next(v.begin(), 2);
assert(*n == 4);
}
{
auto n = std::ranges::next(v.begin(), v.end());
assert(n == v.end());
}
{
auto n = std::ranges::next(v.begin(), 42, v.end());
assert(n == v.end());
}
}
The example ate, honestly. {3, 1, 4} girlies rise. π
β SEE ALSO β
ranges::prevβ decrement an iterator by a given distance or to a bound;(C++20)(niebloid)ranges::advanceβ advances an iterator by given distance or to a given bound;(C++20)(niebloid)nextβ increment an iterator;(C++11)(function template)
Source: http://cppreference.com Β· version/date: 2024.06.10 β thatβs the cute little sign-off, bestie. Go forth and increment responsibly. πβ¨π¦
π¦ 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