首页 > 编程语言 >【C++】STL 算法 ② ( foreach 循环中传入 函数对象 / Lambda 表达式处理元素 | foreach 循环算法 | Lambda 表达式 - 匿名 函数对象 / 仿函数 )

【C++】STL 算法 ② ( foreach 循环中传入 函数对象 / Lambda 表达式处理元素 | foreach 循环算法 | Lambda 表达式 - 匿名 函数对象 / 仿函数 )

时间:2024-01-08 15:35:12浏览次数:41  
标签:函数 对象 vec Lambda 表达式 foreach



文章目录

  • 一、foreach 循环中传入 函数对象 / Lambda 表达式处理元素
  • 1、foreach 循环算法
  • 2、foreach 循环中传入 函数对象 处理元素
  • 3、foreach 循环中传入 Lambda 表达式 处理元素
  • 4、Lambda 表达式 - 匿名 函数对象 / 仿函数







一、foreach 循环中传入 函数对象 / Lambda 表达式处理元素



1、foreach 循环算法



在 C++ 语言中 , std::foreach 循环 虽然 不是标准库的一部分 , 但是 C ++ 编译器 提供了对 该语法 的支持作为扩展 ;

使用 该 std::foreach 循环 , 可以用于 遍历 STL 标准模板库 中提供的容器

std::for_each 是一个算法 , 该算法 接受一对迭代器 , 表示 容器 的 起始位置 和 结束位置 和 一个可调用对象 , 如 : 函数 / 函数指针 / 仿函数 / 函数对象 / Lambda 表达式 , 并对范围内的每个元素调用该可调用对象 ;

注意 : 上述 迭代器 范围 是一个 前闭后开 区间 ;



2、foreach 循环中传入 函数对象 处理元素



使用 foreach 循环遍历 STL 容器 中的元素时 , 可以对 被遍历的 元素 使用 函数对象 / 仿函数 , 这三个是同一个概念 , 相当于 在循环体中调用该 函数对象 / 仿函数 中的 " 重载 函数调用操作符 () 函数 " ;



在下面的代码中 , 自定义了 PrintT 仿函数类 , 该类对象可以 直接当做函数一样调用 ;

//函数对象 类重载了()
template <typename T>
class PrintT{
public:
	void operator()(T& t){
		cout << t << endl;
	}
};

向 foreach 循环中 , 直接传入该 仿函数类 对象 ( 又称为 " 函数对象 " ) ,

for_each(vec.begin(), vec.end(), PrintT<int>());

代码示例 :

#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

//函数对象 类重载了()
template <typename T>
class PrintT{
public:
	void operator()(T& t){
		cout << t << endl;
	}
};

int main() {

	// 创建一个 vector 单端数组容器
	vector<int> vec;

	// 向容器中插入元素
	vec.push_back(1);
	vec.push_back(3);
	vec.push_back(5);

	// 向 foreach 循环中传入函数对象
	// 在函数对象中打印元素内容
	for_each(vec.begin(), vec.end(), PrintT<int>());


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

执行结果 :

1
3
5
Press any key to continue . . .

【C++】STL 算法 ② ( foreach 循环中传入 函数对象 / Lambda 表达式处理元素 | foreach 循环算法 | Lambda 表达式 - 匿名 函数对象 / 仿函数 )_c++



3、foreach 循环中传入 Lambda 表达式 处理元素



在下面的 foreach 循环中 , 传入了 Lambda 表达式 , 该 Lambda 表达式实现的效果

[](int num) {
	std::cout << num << endl;
}

与 函数对象 / 仿函数 实现效果相同 ;

//函数对象 类重载了()
template <typename T>
class PrintT{
public:
	void operator()(T& t){
		cout << t << endl;
	}
};



代码示例 :

#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"

int main() {

	// 创建一个 vector 单端数组容器
	vector<int> vec;

	// 向容器中插入元素
	vec.push_back(1);
	vec.push_back(3);
	vec.push_back(5);

	// 向 foreach 循环中传入 Lambda 表达式
	// 在函数对象中打印元素内容
	for_each(vec.begin(), vec.end(), [](int num) {
		std::cout << num << endl;
	});


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

执行结果 :

1
3
5
Press any key to continue . . .

【C++】STL 算法 ② ( foreach 循环中传入 函数对象 / Lambda 表达式处理元素 | foreach 循环算法 | Lambda 表达式 - 匿名 函数对象 / 仿函数 )_算法_02



4、Lambda 表达式 - 匿名 函数对象 / 仿函数



在上面的代码中 , 使用了 Lambda 表达式 , 如下所示 :

// 向 foreach 循环中传入 Lambda 表达式
	// 在函数对象中打印元素内容
	for_each(vec.begin(), vec.end(), [](int num) {
		std::cout << num << endl;
	});

Lambda 表达式 是一个 匿名的 函数对象 / 仿函数 ;



Lambda 表达式 语法如下 :

[capture](parameters) -> return_type { body_of_lambda }
  • capture 捕获列表 : 指定哪些外部变量可以在 lambda 函数体内被访问到 ;
  • parameters 参数列表 : 和普通函数的参数列表类似 ;
  • return_type 返回类型 : 可省略 , 如果在 函数体中返回某个值 , 编译器会自动推导返回类型 ;
  • body_of_lambda 函数体 : 实现特定功能 ;


capture 捕获列表 语法 :

  • [x] : 通过 值捕获 x ;
  • [&y] : 通过 引用捕获 y ;
  • [=] : 通过值 捕获所有外部变量 ;
  • [&] : 通过引用 捕获所有外部变量 ;
  • [this] : 捕获当前类的 this 指针 ;


上述 foreach 循环中 , 没有捕获外部的变量 , 传入了 int 类型的参数 , 在函数体内打印了 int 类型参数 ; 这个 int 类型的参数就是 STL 容器中的值 ;

[](int num) {
	std::cout << num << endl;
}


标签:函数,对象,vec,Lambda,表达式,foreach
From: https://blog.51cto.com/u_14202100/9145510

相关文章

  • 无涯教程-Redis - SDIFF命令函数
    RedisSDIFF命令返回一个集合与给定集合的差集的元素.SDIFF-返回值返回数组,结果集的元素.SDIFF-语法以下是RedisSDIFF命令的基本语法。redis127.0.0.1:6379>SDIFFFIRST_KEYOTHER_KEY1..OTHER_KEYNSDIFF-示例redis127.0.0.1:6379>SADDmyset"hello"(in......
  • 无涯教程-Redis - RPOPLPUSH命令函数
    RedisRPOPLPUSH命令返回并删除源(source)中存储的列表的最后一个元素,并将该元素压入存储在目标位置的列表的第一个元素(头)。RPOPLPUSH-返回值返回被弹出的最后一个元素。RPOPLPUSH-语法以下是RedisRPOPLPUSH命令的基本语法。redis127.0.0.1:6379>RPOPLPUSHSOU......
  • 无涯教程-Redis - LREM命令函数
    RedisLREM命令从存储在键处的列表中删除等于该值的元素的首次计数出现,count参数通过以下方式影响操作-count>0- 删除等于从头到尾移动的值的元素。count<0- 删除等于从尾到头移动的值的元素。count=0  - 删除所有等于value的元素。LREM-返回值返回整数,已......
  • 【C语言】函数栈帧的创建和销毁
    1、什么是函数栈帧我们在写C语言代码的时候,经常会把一个独立的功能抽象为函数,所以C程序是以函数为基本单位的。那函数是如何调用的?函数的返回值又是如何待会的?函数参数是如何传递的?这些问题都和函数栈帧有关系。函数栈帧(stackframe)就是函数调用过程中在程序的调用栈(callstack)所......
  • 无涯教程-Redis - LPUSH命令函数
    RedisLPUSH命令将所有指定的值插入存储在键处的列表的开头,如果键不存在,则创建空列表,当键包含的值不是列表时,将返回错误。LPUSH-返回值返回操作后列表的长度。LPUSH-语法以下是RedisLPUSH命令的基本语法。redis127.0.0.1:6379>LPUSHKEY_NAMEVALUE1..VALUENLP......
  • 无涯教程-Redis - LLEN命令函数
    RedisLLEN命令返回存储在键处的列表的长度,如果键不存在,则返回0,当键上存储的值不是列表时,将返回错误。LLEN-返回值返回整数,列表的长度在关键处。LLEN-语法以下是RedisLLEN命令的基本语法。redis127.0.0.1:6379>LLENKEY_NAMELLEN-示例redis127.0.0.1:6379>......
  • 无涯教程-Redis - LINSERT命令函数
    RedisLINSERT命令将参考值枢轴(pivot)之前或之后的值插入存储在键处的列表中,如果键不存在,则不执行任何操作。当键存在但不包含列表值时,将返回错误。LINSERT-返回值返回整数,即插入操作后列表的长度,如果未找到值透视点,则返回-1。LINSERT-语法以下是RedisLINSERT命令......
  • 无涯教程-Redis - LINDEX命令函数
    RedisLINDEX命令用于获取存储在键处的列表中索引处的元素。索引从零开始,因此0表示第一个元素,1表示第二个元素,依此类推。负索引可用于指定从列表末尾开始的元素,在这里,-1表示最后一个元素,-2表示倒数第二个,依此类推。LINDEX-返回值返回请求的元素,或者当索引超出范围时为nil。......
  • C 语言函数完全指南:创建、调用、参数传递、返回值解析
    C语言中的函数函数是一段代码块,只有在被调用时才会运行。您可以将数据(称为参数)传递给函数。函数用于执行某些操作,它们对于重用代码很重要:定义一次代码,并多次使用。预定义函数事实证明,您已经知道什么是函数了例如,main()是一个函数,用于执行代码,printf()也是一个函数,用于向屏......
  • 无涯教程-Redis - BRPOPLPUSH命令函数
    RedisBRPOPLPUSH命令用于从列表中返回一个值,或者阻塞直到一个可用,BRPOPLPUSH命令仅返回最后一个元素并将其插入到另一个列表(如果有)中,或者在特定时间内阻止客户端执行任何命令。BRPOPLPUSH-返回值如果键存在,则返回值,否则返回nil。BRPOPLPUSH-语法以下是RedisBRPOP......