当前位置: 首页 > 工具软件 > Each > 使用案例 >

c++中的 for_each 函数

锺离森
2023-12-01

c++中的 for_each 函数

在C++中,for_each是一个通用的算法,用于对容器中的所有元素执行给定的函数。for_each函数是定义在头文件中的,它是C++标准库的一部分。for_each主要用于遍历容器,如vector、list、set等,对容器中的每个元素执行特定操作。
for_each()事实上是個 function template,其源码如下:

template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn);

参数:

  • first 输入迭代器,指向容器中第一个元素
  • last 输入迭代器,指向容器中最后一个元素的下一个位置
  • fn 一个可调用对象(函数指针、函数对象或Lambda表达式),它接受容器中元素的引用作为参数

返回值:

  • for_each函数返回传入的可调用对象(Function类型的对象)

for_each() 是一个非常有用的函数,它有助于在 STL 容器中的每个元素上调用函数对象fn。这实际上有助于编写简短的代码并减少我们代码库的大小。以下几种fn调用的情况:

1、lambda方式

#include <iostream>
#include <algorithm>
#include <vector>

int main()
{
    std::vector<int> vec;
    size_t count = 10;
    for (size_t i = 0; i < count; i++)
    {
        vec.emplace_back(i + 1);
    }

    std::for_each(vec.begin(), vec.end(), [&](int value)
                  { std::cout << value << std::endl; });
    system("pause");
    return 0;
}

遍历结果:

1 2 3 4 5 6 7 8 9 10 

2、普通函数

#include <iostream>
#include <vector>
#include <algorithm>

void increment(int& value) 
{
    value++;
}

int main() 
{
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::for_each(numbers.begin(), numbers.end(), increment);
    for (int number : numbers) {
        std::cout << number << " ";
    }
    return 0;
}

遍历结果:

2 3 4 5 6

3、仿函数

#include <iostream>
#include <vector>
#include <algorithm>

class Fun
{
public:
    void operator() (const int num) 
    {
         std::cout << num << " ";
    }
};

int main() 
{
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::for_each(numbers.begin(), numbers.end(), Fun());
    return 0;
}

遍历结果:

1 2 3 4 5 

使用 for_each() 的好处是它减少了代码库的大小并使代码产品级别。此外,时间复杂度为 O(n)。如果有任何情况,其中每个元素都经过大型代码库的大量处理,您可以使用 for_each()

注:并行功能

在C++17中,std::for_each函数得到了扩展,增加了支持并行算法的功能。新版本的std::for_each允许在多个线程中并发地执行操作,以提高性能。这是通过添加一个名为ExecutionPolicy的额外参数实现的,这个参数指定了执行策略。
std::for_each的并行版本原型如下:

template< class ExecutionPolicy, class ForwardIt, class UnaryFunction >
UnaryFunction for_each(ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryFunction f);

参数:

  • policy:一个执行策略对象,指示算法的并行执行方式。可选的执行策略有:
    • std::execution::seq:顺序执行(非并行)
    • std::execution::par:并行执行
    • std::execution::par_unseq:并行和向量化执行
  • first:迭代器,指向容器中第一个元素
  • last:迭代器,指向容器中最后一个元素的下一个位置
  • f:一个可调用对象(函数指针、函数对象或Lambda表达式),它接受容器中元素的引用作为参数

要使用并行版本的std::for_each,需要包含头文件,并将合适的执行策略传递给函数,下面是一个简单的示例,演示了如何使用并行std::for_each遍历std::vector容器,并为每个元素加1:

#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>

int main() 
{
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::for_each(std::execution::par, numbers.begin(), numbers.end(), [](int& value) {
        value++;
    });
    for (int number : numbers) {
        std::cout << number << " ";
    }
    return 0;
}

输出结果(注意,由于并行执行,输出顺序可能会有所不同):

2 3 4 5 6

请注意,并行版本的std::for_each要求编译器和标准库支持C++17及以上版本。另外,并行版本可能并不总是比顺序版本更快,因为它可能受到硬件、数据量、可调用对象的复杂性等因素的影响。在选择并行版本之前,最好先进行性能测试。

 类似资料: