Skip to main content

std::ranges::for_each_n() algorithm

// (1)
constexpr for_each_n_result<I, Fun>
for_each_n( I first, std::iter_difference_t<I> n, Fun f, Proj proj = {});

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • Fun - std::indirectly_unary_invocable<std::projected<I, Proj>>
  • Proj - (none)

The Proj template argument has a default type of std::identity.

With the helper types defined as follows:

template< class I, class F >
using for_each_n_result = ranges::in_fun_result<I, F>;
  • (1) Applies the given function object f to the result of the value projected by each iterator in the range [first, first + n), in order.

For both overloads, if the iterator type is mutable, f may modify the elements of the range. If f returns a result, the result is ignored.

Undefined Behaviour

If n is less than zero, the behavior is undefined

.

The function-like entities described on this page are niebloids.

Parameters

first
last

The beginning of the range to apply the function to.

n

The number of elements to apply the function to.

proj

Projection to apply to the elements.

f

Function object, to be applied to every element of the range. The signature of the function should be equivalent to the following:

void fun(const Type& a);
  • The signature does not need to have const&.
  • The type Type must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type.

Return value

An object of of type for_each_n_result initialized as follows:

{
first + n,
std::move(f)
}

Where first + n may be evaluated as std::ranges::next(std::move(first), n) depending on iterator category.

Complexity

Exactly n applications of f and proj.

Exceptions

(none)

Possible implementation

for_each_n(1)
struct for_each_n_fn
{
template<std::input_iterator I, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<I, Proj>> Fun>
constexpr for_each_n_result<I, Fun>
operator()(I first, std::iter_difference_t<I> n, Fun fun, Proj proj = Proj{}) const
{
for (; n-- > 0; ++first)
std::invoke(fun, std::invoke(proj, *first));
return {std::move(first), std::move(fun)};
}
};

inline constexpr for_each_n_fn for_each_n {};

Examples

Main.cpp
#include <algorithm>
#include <array>
#include <iostream>
#include <ranges>
#include <string_view>

struct P
{
int first;
char second;
friend std::ostream& operator<<(std::ostream& os, const P& p)
{
return os << '{' << p.first << ",'" << p.second << "'}";
}
};

auto print = [](std::string_view name, auto const& v)
{
std::cout << name << ": ";
for (auto n = v.size(); const auto& e : v)
std::cout << e << (--n ? ", " : "\n");
};

int main()
{
std::array a {1, 2, 3, 4, 5};
print("a", a);
// Negate first three numbers:
std::ranges::for_each_n(a.begin(), 3, [](auto& n) { n *= -1; });
print("a", a);

std::array s { P{1,'a'}, P{2, 'b'}, P{3, 'c'}, P{4, 'd'} };
print("s", s);
// Negate data members 'P::first' using projection:
std::ranges::for_each_n(s.begin(), 2, [](auto& x) { x *= -1; }, &P::first);
print("s", s);
// Capitalize data members 'P::second' using projection:
std::ranges::for_each_n(s.begin(), 3, [](auto& c) { c -= 'a'-'A'; }, &P::second);
print("s", s);
}
Output
a: 1, 2, 3, 4, 5
a: -1, -2, -3, 4, 5
s: {1,'a'}, {2,'b'}, {3,'c'}, {4,'d'}
s: {-1,'a'}, {-2,'b'}, {3,'c'}, {4,'d'}
s: {-1,'A'}, {-2,'B'}, {3,'C'}, {4,'d'}
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::for_each_n() algorithm

// (1)
constexpr for_each_n_result<I, Fun>
for_each_n( I first, std::iter_difference_t<I> n, Fun f, Proj proj = {});

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • Fun - std::indirectly_unary_invocable<std::projected<I, Proj>>
  • Proj - (none)

The Proj template argument has a default type of std::identity.

With the helper types defined as follows:

template< class I, class F >
using for_each_n_result = ranges::in_fun_result<I, F>;
  • (1) Applies the given function object f to the result of the value projected by each iterator in the range [first, first + n), in order.

For both overloads, if the iterator type is mutable, f may modify the elements of the range. If f returns a result, the result is ignored.

Undefined Behaviour

If n is less than zero, the behavior is undefined

.

The function-like entities described on this page are niebloids.

Parameters

first
last

The beginning of the range to apply the function to.

n

The number of elements to apply the function to.

proj

Projection to apply to the elements.

f

Function object, to be applied to every element of the range. The signature of the function should be equivalent to the following:

void fun(const Type& a);
  • The signature does not need to have const&.
  • The type Type must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type.

Return value

An object of of type for_each_n_result initialized as follows:

{
first + n,
std::move(f)
}

Where first + n may be evaluated as std::ranges::next(std::move(first), n) depending on iterator category.

Complexity

Exactly n applications of f and proj.

Exceptions

(none)

Possible implementation

for_each_n(1)
struct for_each_n_fn
{
template<std::input_iterator I, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<I, Proj>> Fun>
constexpr for_each_n_result<I, Fun>
operator()(I first, std::iter_difference_t<I> n, Fun fun, Proj proj = Proj{}) const
{
for (; n-- > 0; ++first)
std::invoke(fun, std::invoke(proj, *first));
return {std::move(first), std::move(fun)};
}
};

inline constexpr for_each_n_fn for_each_n {};

Examples

Main.cpp
#include <algorithm>
#include <array>
#include <iostream>
#include <ranges>
#include <string_view>

struct P
{
int first;
char second;
friend std::ostream& operator<<(std::ostream& os, const P& p)
{
return os << '{' << p.first << ",'" << p.second << "'}";
}
};

auto print = [](std::string_view name, auto const& v)
{
std::cout << name << ": ";
for (auto n = v.size(); const auto& e : v)
std::cout << e << (--n ? ", " : "\n");
};

int main()
{
std::array a {1, 2, 3, 4, 5};
print("a", a);
// Negate first three numbers:
std::ranges::for_each_n(a.begin(), 3, [](auto& n) { n *= -1; });
print("a", a);

std::array s { P{1,'a'}, P{2, 'b'}, P{3, 'c'}, P{4, 'd'} };
print("s", s);
// Negate data members 'P::first' using projection:
std::ranges::for_each_n(s.begin(), 2, [](auto& x) { x *= -1; }, &P::first);
print("s", s);
// Capitalize data members 'P::second' using projection:
std::ranges::for_each_n(s.begin(), 3, [](auto& c) { c -= 'a'-'A'; }, &P::second);
print("s", s);
}
Output
a: 1, 2, 3, 4, 5
a: -1, -2, -3, 4, 5
s: {1,'a'}, {2,'b'}, {3,'c'}, {4,'d'}
s: {-1,'a'}, {-2,'b'}, {3,'c'}, {4,'d'}
s: {-1,'A'}, {-2,'B'}, {3,'C'}, {4,'d'}
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.