前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++】STL 算法 - for_each 遍历算法 ( for_each 函数原型 | for_each 函数源码分析 | for_each 函数 _Fn _Func 参数 值传递说明 )

【C++】STL 算法 - for_each 遍历算法 ( for_each 函数原型 | for_each 函数源码分析 | for_each 函数 _Fn _Func 参数 值传递说明 )

作者头像
韩曙亮
发布2024-01-14 09:58:06
1800
发布2024-01-14 09:58:06
举报
文章目录
  • 一、for_each 算法
    • 1、for_each 函数简介
    • 2、for_each 函数原型
    • 3、for_each 函数源码分析
    • 4、for_each 函数 _Fn _Func 参数 值传递说明
  • 二、代码示例 - for_each 算法
    • 1、代码示例 - for_each 算法 传入普通函数
    • 2、代码示例 - for_each 算法 传入 Lambda 表达式
    • 3、代码示例 - for_each 算法 传入一元函数对象
    • 4、代码示例 - for_each 算法 函数对象 值传递

一、for_each 算法


1、for_each 函数简介

在 C++ 语言 的 标准模板库 ( STL , Standard Template Library ) 中 , 提供了 for_each 算法 用于 对一个 STL 容器中的每个元素执行某个指定的 " 操作 " ;

for_each 算法 中 执行的 " 操作 " 可以是一个 函数 / 函数对象 / Lambda 表达式 ;

在 for_each 函数 中 可以修改 被遍历的元素 , 也可以 不修改 元素 ;

2、for_each 函数原型

for_each 算法 函数原型 : 将 迭代器 范围 内的所有元素 传入 一个参数的 可调用对象 , 逐个遍历 执行上述操作 ;

代码语言:javascript
复制
template <class InputIt, class Function>  
Function for_each(InputIt first, InputIt last, Function f);
  • 参数解析 :
    • InputIt first 参数 : 要遍历的 迭代器范围 的 起始迭代器 , first 参数 是指向序列中 第一个元素 的迭代器 ; 这是 " 前闭后开区间 " 的 起始闭区间 ;
    • InputIt last 参数 : 要遍历的 迭代器范围 的 终止迭代器 , last 参数 是指向序列中 最后一个元素 之后 位置 的迭代器 ; 这是 " 前闭后开区间 " 的 末尾开区间 ;
    • Function f 参数 : 接收一个参数的可调用对象 , 可以是 一元函数对象 或者 接收一个参数的 普通函数 / Lambda 表达式 , 将 迭代器范围 内的 所有元素 , 传入该 可调用对象 中 ,
    • 迭代器范围 解析 : 是一个 " 前闭后开区间 " , 起始迭代器指向的元素包含在范围之内 , 终止迭代器 指向的元素 不包含在范围之内 , 如果 终止迭代器 是 末尾迭代器 end() , 那么 指向无意义元素 ;
  • 返回值解析 : 该算法函数 的 返回值是 传入的函数对象 ;
    • 保存状态 : 如果传入的是 函数对象 , 这一返回值特性使得 作为参数传入的 函数对象 可以在 for_each 调用之后保持其状态 , 这里的 " 状态 " 指的是 函数对象 类 中的 成员变量 ; 如果 传入的事 普通函数 或 Lambda 表达式 , 则没有状态 ;
    • 链式调用 : 返回值 是 传入的 可调用对象 本身 , 可用于 实现 " 链式调用 " ;

3、for_each 函数源码分析

for_each 源代码如下 :

代码语言:javascript
复制
// FUNCTION TEMPLATE for_each
template <class _InIt, class _Fn>
_Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) { // perform function for each element [_First, _Last)
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
        _Func(*_UFirst);
    }

    return _Func;
}

该 函数 是一个 " 模板函数 " , 第一个 模板类型 _InIt 是 迭代器类型 , 第二个 模板类型 _Fn 是 可调用对象 类型 , 该可调用对象 接收 一个 函数参数 , 可以是 函数对象 / 普通函数 ,

在该 模板函数 中 , 遍历 _InIt _First 和 _InIt _Last 范围的元素 , 传入到 _Func 函数对象 中 , 调用完成后 , 将 _Func 函数对象 返回 , 该函数可进行 链式调用 ;

4、for_each 函数 _Fn _Func 参数 值传递说明

这里特别注意 : 传入的 _Fn _Func 参数 是 函数对象 , 该参数类型是 值 类型 , 不是 引用 或 一维指针 类型 , 因此 该 传入的参数 是 值传递 , 传入参数 是 实参 的副本 ,

也就是 将 函数对象 A 传入到 for_each 函数中 , 此时会将 A 对象 赋值一份副本 B 传入到 for_each 中 , 在 for_each 函数中使用的是 对象 B , 然后返回的也是 对象 B ;

二、代码示例 - for_each 算法


1、代码示例 - for_each 算法 传入普通函数

代码示例 :

代码语言:javascript
复制
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

// 普通函数
void printElement(int& n)
{
	cout << n << " ";
}

int main() {

	// 创建一个 set 集合容器
	vector<int> myVector;

	// 向容器中插入元素
	myVector.push_back(9);
	myVector.push_back(5);
	myVector.push_back(2);
	myVector.push_back(7);
	myVector.push_back(2);

	// 向 foreach 循环中传入 Lambda 表达式
	for_each(myVector.begin(), myVector.end(), printElement);
	cout << endl;

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
};

执行结果 :

代码语言:javascript
复制
9 5 2 7 2
请按任意键继续. . .
在这里插入图片描述
在这里插入图片描述

2、代码示例 - for_each 算法 传入 Lambda 表达式

代码示例 :

代码语言:javascript
复制
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

int main() {

	// 创建一个 set 集合容器
	vector<int> myVector;

	// 向容器中插入元素
	myVector.push_back(9);
	myVector.push_back(5);
	myVector.push_back(2);
	myVector.push_back(7);
	myVector.push_back(2);

	// 向 foreach 循环中传入 Lambda 表达式
	for_each(myVector.begin(), myVector.end(), [](int a) {
		std::cout << a << " ";
		});
	cout << endl;

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
};

执行结果 :

代码语言:javascript
复制
9 5 2 7 2
请按任意键继续. . .
在这里插入图片描述
在这里插入图片描述

3、代码示例 - for_each 算法 传入一元函数对象

代码示例 :

代码语言:javascript
复制
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

// 一元函数对象
class PrintElement{
public:
	PrintElement(){
		count = 0;
	}
	void operator()(int& n){
		cout << count << ". " << n << " , ";
		count++;
	}
private:
	int count;
};

int main() {

	// 创建一个 vector 集合容器
	vector<int> myVector;

	// 向容器中插入元素
	myVector.push_back(9);
	myVector.push_back(5);
	myVector.push_back(2);
	myVector.push_back(7);
	myVector.push_back(2);

	// 向 foreach 循环中传入 Lambda 表达式
	for_each(myVector.begin(), myVector.end(), PrintElement());
	cout << endl;

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
};

执行结果 :

代码语言:javascript
复制
0. 9 , 1. 5 , 2. 2 , 3. 7 , 4. 2 ,
请按任意键继续. . .
在这里插入图片描述
在这里插入图片描述

4、代码示例 - for_each 算法 函数对象 值传递

代码示例 :

代码语言:javascript
复制
#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

// 一元函数对象
class PrintElement{
public:
	PrintElement(){
		count = 0;
	}
	void operator()(int& n){
		cout << count << ". " << n << " , ";
		count++;
	}
	void printCount() {
		cout << "count = " << count << endl;
	}
private:
	int count;
};

int main() {

	// 创建一个 vector 集合容器
	vector<int> myVector;

	// 向容器中插入元素
	myVector.push_back(9);
	myVector.push_back(5);
	myVector.push_back(2);
	myVector.push_back(7);
	myVector.push_back(2);

	// 向 foreach 循环中传入 Lambda 表达式
	auto PE1 = PrintElement();
	auto PE2 = for_each(myVector.begin(), myVector.end(), PE1);
	cout << endl;

	PE1.printCount();
	PE2.printCount();

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
	return 0;
};

执行结果 :

代码语言:javascript
复制
0. 9 , 1. 5 , 2. 2 , 3. 7 , 4. 2 ,
count = 0
count = 5
请按任意键继续. . .
在这里插入图片描述
在这里插入图片描述
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、for_each 算法
    • 1、for_each 函数简介
      • 2、for_each 函数原型
        • 3、for_each 函数源码分析
          • 4、for_each 函数 _Fn _Func 参数 值传递说明
          • 二、代码示例 - for_each 算法
            • 1、代码示例 - for_each 算法 传入普通函数
              • 2、代码示例 - for_each 算法 传入 Lambda 表达式
                • 3、代码示例 - for_each 算法 传入一元函数对象
                  • 4、代码示例 - for_each 算法 函数对象 值传递
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                  http://www.vxiaotou.com