跳到主要内容

std::ranges::for_each() 算法

// (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 = {} );

参数类型是泛型的,并具有以下约束:

  • 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 - (无)

对于所有重载,Proj 模板参数的默认类型为 std::identity

辅助类型定义如下:

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

将给定函数应用于范围中的所有元素。

  • (1) 依次将给定的函数对象 f 应用于范围 [first, last) 中每个迭代器投射的值的结果。

  • (2)(1) 相同,但使用 r 作为源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

对于两个重载,如果迭代器类型是可变的,f 可以修改范围的元素。如果 f 返回结果,则结果将被忽略。

本页描述的函数类实体是niebloids

参数

first
last

要应用函数的元素范围。

r

要应用函数的元素范围。

proj

应用于元素的投影。

f

函数对象,应用于范围的每个元素。函数的签名应等效于以下内容

void fun(const Type& a);
  • 签名不需要包含 const&
  • 类型 Type 必须是这样的,即 InputIt 类型的对象可以被解引用,然后隐式转换为 Type

返回值

类型为 for_each_result 的值,初始化如下

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

复杂度

精确地 last - firstfproj 的应用。

异常

(无)

可能的实现

for_each(1) 和 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;

示例

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');
}
输出
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
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::ranges::for_each() 算法

// (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 = {} );

参数类型是泛型的,并具有以下约束:

  • 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 - (无)

对于所有重载,Proj 模板参数的默认类型为 std::identity

辅助类型定义如下:

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

将给定函数应用于范围中的所有元素。

  • (1) 依次将给定的函数对象 f 应用于范围 [first, last) 中每个迭代器投射的值的结果。

  • (2)(1) 相同,但使用 r 作为源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

对于两个重载,如果迭代器类型是可变的,f 可以修改范围的元素。如果 f 返回结果,则结果将被忽略。

本页描述的函数类实体是niebloids

参数

first
last

要应用函数的元素范围。

r

要应用函数的元素范围。

proj

应用于元素的投影。

f

函数对象,应用于范围的每个元素。函数的签名应等效于以下内容

void fun(const Type& a);
  • 签名不需要包含 const&
  • 类型 Type 必须是这样的,即 InputIt 类型的对象可以被解引用,然后隐式转换为 Type

返回值

类型为 for_each_result 的值,初始化如下

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

复杂度

精确地 last - firstfproj 的应用。

异常

(无)

可能的实现

for_each(1) 和 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;

示例

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');
}
输出
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
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。