Namespaces
Variants

std:: for_each

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
for_each
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
定义于头文件 <algorithm>
template < class InputIt, class UnaryFunc >
UnaryFunc for_each ( InputIt first, InputIt last, UnaryFunc f ) ;
(1) (自 C++20 起为 constexpr)
template < class ExecutionPolicy, class ForwardIt, class UnaryFunc >

void for_each ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, UnaryFunc f ) ;
(2) (自 C++17 起)

对范围 [ first , last ) 中的每个 迭代器 解引用结果应用给定的 函数对象 f 。如果 f 返回结果,该结果将被忽略。

1) f 按顺序从 first 开始应用。

UnaryFunc 不满足 MoveConstructible ,则 行为未定义

(C++11 起)
2) f 可能不会按顺序应用。该算法根据 policy 执行。
此重载仅在满足以下所有条件时参与重载决议:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> true

(C++20 前)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> true

(C++20 起)
如果 UnaryFunc 不满足 可复制构造 要求,则 行为未定义

如果迭代器类型( InputIt / ForwardIt )是可变的, f 可能通过解引用迭代器来修改 范围 内的元素。

与其他并行算法不同, for_each 不允许复制序列中的元素,即使它们是 TriviallyCopyable 的。

目录

参数

first, last - 定义要应用 函数对象 的元素 范围 的迭代器对
policy - 要使用的 执行策略
f - 函数对象,将应用于 范围 [ first , last ) 中每个迭代器解引用结果

函数签名应等价于:

void fun ( const Type & a ) ;

签名无需包含 const &
类型 Type 必须满足: InputIt 类型的对象在解引用后可隐式转换为 Type

类型要求
-
InputIt 必须满足 LegacyInputIterator 的要求。
-
ForwardIt 必须满足 LegacyForwardIterator 的要求。

返回值

1) f
2) (无)

复杂度

恰好应用 std:: distance ( first, last ) f

异常

带有名为 ExecutionPolicy 模板参数的重载按以下方式报告错误:

  • 如果作为算法一部分调用的函数执行抛出异常,且 ExecutionPolicy 是某个 标准策略 ,则调用 std::terminate 。对于其他任何 ExecutionPolicy ,其行为由实现定义。
  • 如果算法无法分配内存,则抛出 std::bad_alloc

可能的实现

另请参阅 libstdc++ libc++ MSVC stdlib 中的实现。

template<class InputIt, class UnaryFunc>
constexpr UnaryFunc for_each(InputIt first, InputIt last, UnaryFunc f)
{
    for (; first != last; ++first)
        f(*first);
    return f; // 自 C++11 起隐式移动
}

注释

对于重载 ( 1 ) f 可以是带状态的函数对象。返回值可视为批处理操作的最终状态。

对于重载 ( 2 ) ,可能会创建多个 f 的副本来执行并行调用。该重载不返回值,因为并行化通常无法实现高效的状态累积。

示例

以下示例使用 lambda表达式 对vector中的所有元素进行递增操作,随后通过函数对象(亦称"仿函数")中重载的 operator() 计算其总和。注意在实际求和时,推荐使用专用算法 std::accumulate

#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
    std::vector<int> v{3, -4, 2, -8, 15, 267};
    auto print = [](const int& n) { std::cout << n << ' '; };
    std::cout << "before:\t";
    std::for_each(v.cbegin(), v.cend(), print);
    std::cout << '\n';
    // 就地递增元素
    std::for_each(v.begin(), v.end(), [](int &n) { n++; });
    std::cout << "after:\t";
    std::for_each(v.cbegin(), v.cend(), print);
    std::cout << '\n';
    struct Sum
    {
        void operator()(int n) { sum += n; }
        int sum {0};
    };
    // 对每个元素调用 Sum::operator()
    Sum s = std::for_each(v.cbegin(), v.cend(), Sum());    
    std::cout << "sum:\t" << s.sum << '\n';
}

输出:

before:	3 -4 2 -8 15 267 
after:	4 -3 3 -7 16 268 
sum:	281

缺陷报告

下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

缺陷报告 适用标准 发布时行为 正确行为
LWG 475 C++98 未明确说明 f 是否可以修改正在迭代的序列元素
for_each 被归类为“非修改型序列操作”)
已明确说明(当迭代器类型为可变时允许修改)
LWG 2747 C++11 重载 ( 1 ) 返回 std :: move ( f ) 返回 f (隐式移动)

参见

对元素范围应用函数,并将结果存储到目标范围中
(函数模板)
(C++17)
对序列的前N个元素应用函数对象
(函数模板)
范围 中的元素应用一元 函数对象
(算法函数对象)
对序列的前N个元素应用函数对象
(算法函数对象)
range- for loop (C++11) 在范围上执行循环