Skip to main content

std::ranges::for_each() algorithm

// (1)
constexpr for_each_result<I, Fun>
for_each( I first, S last, Fun f, Proj proj = {} );


// (2)
constexpr for_each_result<ranges::borrowed_iterator_t<R>, Fun>
for_each( R&& r, Fun f, Proj proj = {} );

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • R - std::ranges::input_range
  • Fun:
    • (1) - std::indirectly_unary_invocable<std::projected<I, Proj>>
    • (2) - std::indirectly_unary_invocable<std::projected<ranges::iterator_t<R>, Proj>>
  • Proj - (none)

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

With the helper types defined as follows:

template< class I, class F >
using for_each_result = ranges::in_fun_result<I, F>;

Applies the given function to all elements in range.

  • (1) Applies the given function object f to the result of the value projected by each iterator in the range [first, last), in order.

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

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.

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

Parameters

first
last

The range of elements to apply the function to.

r

The range 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

Value of type for_each_result initialized as follows:

{
std::ranges::next(std::move(first), last),
std::move(f)
}

Complexity

Exactly last - first applications of f and proj.

Exceptions

(none)

Possible implementation

for_each(1) and for_each(2)
struct for_each_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<I, Proj>> Fun>
constexpr ranges::for_each_result<I, Fun>
operator()(I first, S last, Fun f, Proj proj = {}) const
{
for (; first != last; ++first)
std::invoke(f, std::invoke(proj, *first));
return {std::move(first), std::move(f)};
}

template<ranges::input_range R, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<ranges::iterator_t<R>,
Proj>> Fun>
constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun>
operator()(R&& r, Fun f, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(f), std::ref(proj));
}
};

inline constexpr for_each_fn for_each;

Examples

Main.cpp
#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

struct Sum
{
void operator()(int n) { sum += n; }
int sum {0};
};

int main()
{
std::vector<int> nums {3, 4, 2, 8, 15, 267};

auto print = [](const auto& n) { std::cout << ' ' << n; };

namespace ranges = std::ranges;
std::cout << "before:";
ranges::for_each(std::as_const(nums), print);
print('\n');

ranges::for_each(nums, [](int& n) { ++n; });

// calls Sum::operator() for each number
auto [i, s] = ranges::for_each(nums.begin(), nums.end(), Sum());
assert(i == nums.end());

std::cout << "after: ";
ranges::for_each(nums.cbegin(), nums.cend(), print);

std::cout << "\n" "sum: " << s.sum << '\n';

using pair = std::pair<int, std::string>;
std::vector<pair> pairs {{1,"one"}, {2,"two"}, {3,"tree"}};

std::cout << "project the pair::first: ";
ranges::for_each(pairs, print, [](const pair& p) { return p.first; });

std::cout << "\n" "project the pair::second:";
ranges::for_each(pairs, print, &pair::second);
print('\n');
}
Output
before: 3 4 2 8 15 267 
after: 4 5 3 9 16 268
sum: 305
project the pair::first: 1 2 3
project the pair::second: one two tree
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() algorithm

// (1)
constexpr for_each_result<I, Fun>
for_each( I first, S last, Fun f, Proj proj = {} );


// (2)
constexpr for_each_result<ranges::borrowed_iterator_t<R>, Fun>
for_each( R&& r, Fun f, Proj proj = {} );

The type of arguments are generic and have following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • R - std::ranges::input_range
  • Fun:
    • (1) - std::indirectly_unary_invocable<std::projected<I, Proj>>
    • (2) - std::indirectly_unary_invocable<std::projected<ranges::iterator_t<R>, Proj>>
  • Proj - (none)

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

With the helper types defined as follows:

template< class I, class F >
using for_each_result = ranges::in_fun_result<I, F>;

Applies the given function to all elements in range.

  • (1) Applies the given function object f to the result of the value projected by each iterator in the range [first, last), in order.

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

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.

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

Parameters

first
last

The range of elements to apply the function to.

r

The range 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

Value of type for_each_result initialized as follows:

{
std::ranges::next(std::move(first), last),
std::move(f)
}

Complexity

Exactly last - first applications of f and proj.

Exceptions

(none)

Possible implementation

for_each(1) and for_each(2)
struct for_each_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<I, Proj>> Fun>
constexpr ranges::for_each_result<I, Fun>
operator()(I first, S last, Fun f, Proj proj = {}) const
{
for (; first != last; ++first)
std::invoke(f, std::invoke(proj, *first));
return {std::move(first), std::move(f)};
}

template<ranges::input_range R, class Proj = std::identity,
std::indirectly_unary_invocable<std::projected<ranges::iterator_t<R>,
Proj>> Fun>
constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun>
operator()(R&& r, Fun f, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(f), std::ref(proj));
}
};

inline constexpr for_each_fn for_each;

Examples

Main.cpp
#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

struct Sum
{
void operator()(int n) { sum += n; }
int sum {0};
};

int main()
{
std::vector<int> nums {3, 4, 2, 8, 15, 267};

auto print = [](const auto& n) { std::cout << ' ' << n; };

namespace ranges = std::ranges;
std::cout << "before:";
ranges::for_each(std::as_const(nums), print);
print('\n');

ranges::for_each(nums, [](int& n) { ++n; });

// calls Sum::operator() for each number
auto [i, s] = ranges::for_each(nums.begin(), nums.end(), Sum());
assert(i == nums.end());

std::cout << "after: ";
ranges::for_each(nums.cbegin(), nums.cend(), print);

std::cout << "\n" "sum: " << s.sum << '\n';

using pair = std::pair<int, std::string>;
std::vector<pair> pairs {{1,"one"}, {2,"two"}, {3,"tree"}};

std::cout << "project the pair::first: ";
ranges::for_each(pairs, print, [](const pair& p) { return p.first; });

std::cout << "\n" "project the pair::second:";
ranges::for_each(pairs, print, &pair::second);
print('\n');
}
Output
before: 3 4 2 8 15 267 
after: 4 5 3 9 16 268
sum: 305
project the pair::first: 1 2 3
project the pair::second: one two tree
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.