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

这篇具有很好参考价值的文章主要介绍了【C++】STL 算法 - for_each 遍历算法 ( for_each 函数原型 | for_each 函数源码分析 | for_each 函数 _Fn _Func 参数 值传递说明 )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。





一、for_each 算法



1、for_each 函数简介


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

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

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


2、for_each 函数原型


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

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 源代码如下 :

// 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 算法 传入普通函数


代码示例 :

#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;
};

执行结果 :

9 5 2 7 2
请按任意键继续. . .

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


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


代码示例 :

#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;
};

执行结果 :

9 5 2 7 2
请按任意键继续. . .

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


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


代码示例 :

#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;
};

执行结果 :

0. 9 , 1. 5 , 2. 2 , 3. 7 , 4. 2 ,
请按任意键继续. . .

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


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


代码示例 :

#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;
};

执行结果 :

0. 9 , 1. 5 , 2. 2 , 3. 7 , 4. 2 ,
count = 0
count = 5
请按任意键继续. . .

【C++】STL 算法 - for_each 遍历算法 ( for_each 函数原型 | for_each 函数源码分析 | for_each 函数 _Fn _Func 参数 值传递说明 ),C++,c++,算法,开发语言,stl,for_each,遍历算法,for_each函数文章来源地址https://www.toymoban.com/news/detail-795706.html

到了这里,关于【C++】STL 算法 - for_each 遍历算法 ( for_each 函数原型 | for_each 函数源码分析 | for_each 函数 _Fn _Func 参数 值传递说明 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包