首页 > 其他分享 >仿函数和lambda表达式

仿函数和lambda表达式

时间:2023-12-18 23:32:14浏览次数:23  
标签:函数 int 捕获 列表 表达式 lambda

仿函数和lambda表达式

仿函数

仿函数,就是一种类类型,通过重载调用运算符"()"来实现像函数一样的调用功能,所以称之为仿函数

#include<iostream>
class Add {
private:
	int a;
	int b;
public:
	int operator()(int a, int b) { //operator就是对调用运算符进行重载
		return a + b;
	}
};
int main(void) {
	Add add;
	add(10, 20); //像函数一样的调用,本质是一个类内的成员函数
	return 0;
}

lambda表达式

// lambda表达式实现加法运算
#include<iostream>

auto add = [](int a, int b) {return a + b; }; // lambda表达式,需要用auto来接收器返回值
// []中的值为捕获列表,表示一个局部变量,这里的捕获列表为空

// lambda表达式还可以与尾置返回相联系
auto n_add = [](int a, int b)->decltype(a + b) {return a + b;};

int main(void) {
	std::cout << n_add(10, 20);
	return 0;
}

lambda表达式的基本模板:

auto function_name = [](int T, ...)->decltype(T) {return T; };
// 这里的function_name表示一个lambda表达式名,可以理解成一个函数名
// []中的值是捕获值列表,它表示一个lambda表达式所在函数中定义的局部变量的值的列表,通常为空
// ()中的值是lambda表达式的参数列表,可以理解成函数的参数列表
// 这里的->表示一个尾置返回一般用于decltype声明的返回类型和较为复杂的返回类型
// {}中的是lambda表达式的函数体,如果函数体只是一个return语句,则返回类型由返回的表达式来推断,否则,返回类型为void

注意:模板中的参数列表和返回类型可以省略,但是必须永远包含捕获列表和函数体。

这里的返回类型指的是lambda表达式所要求的尾置返回类型,对于大括号中的return语句,不受影响,因为它属于函数体中的内容。

#include<iostream>
auto func = [] {return 10; };
// 这里的func函数省略了参数列表和返回类型,对于器返回类型,只要它不是复杂类型,编译器可以推导出返回类型

int main(void) {
	std::cout << func() << std::endl;
	return 0;
}

下面再演示一下捕获列表内不为空的情况

#include<iostream>

auto add = [c = 30](int a, int b) ->decltype(a + b) {return a + b + c; };
// 注意,这里捕获列表中的值,只限于在函数体中才能使用,也就是必须在大括号内的内容才可以使用捕获列表中的值
// 捕获列表中不可以使用全局变量或静态变量
// 捕获列表中的值无需声明类型,编译器会自动推导器类型
int main(void) {
	int ans = add(10, 20);
	std::cout << ans << std::endl;
	return 0;
}

捕获列表

捕获列表的使用分为三种形式

1. 值捕获
#include<iostream>
	int main(void) {
	int x = 5;
	auto lambda = [x]() {std::cout << x << std::endl;};
	return 0;
}

使用外部变量的值创建lambda的副本。捕获后,lambda函数体内不能修改这些变量的值。
注意,这里只是外部变量的拷贝而非引用

2. 引用捕获
#include<iostream>
int main(void) {
	int y = 10;
	auto lambda_ref = [&y]() {y++; std::cout << y << std::endl; }; //无return语句,默认返回void
	return 0;
}

使用外部变量的引用。捕获后,lambda函数体内可以修改这些变量的值。
注意,是在函数体内修改

3. 隐式捕获
(1) 按值隐式捕获
#include<iostream>
int main(void) {
	int a = 3, b = 7;
	auto lambda_implicit = [=]() {std::cout << a + b << std::endl;};

	return 0;
}
(2) 按引用隐式捕获
#include<iostream>
int main(void) {
	int aa = 10;
	int& a = aa;
	auto lambda_implicit_ref = [&]() {std::cout << a << std::endl; };

	lambda_implicit_ref();
	return 0;
}

由捕获列表的=或&表示。= 表示按值捕获,& 表示按引用捕获。通过使用 = 或 & ,可以捕获所有可见的外部变量。
这两种捕获同上述捕获的特性一样,比如引用捕获可以修改捕获列表的值

标签:函数,int,捕获,列表,表达式,lambda
From: https://blog.51cto.com/u_16271511/8879362

相关文章

  • 关于奇怪的 Array 函数:
    关于奇怪的Array函数:众所周知,我们可以通过Array函数来做以下事情。初始化一个指定长度的数组。设置数组的初始值。//1.Initializeanarrayofthespecifiedlengthconstarray1=Array(3)//[,,]//2.Settheinitialvalueofthearrayconstarray2=......
  • 无涯教程-Java - SortedSet 集合接口函数
    SortedSet接口扩展了Set并声明了按升序排序的集合的行为。除了Set定义的那些方法外,SortedSet接口还声明了下表中概述的方法-如果尝试使用null对象并且集合中不允许使用null,则抛出NullPointerException。Sr.No.Method&Remark1Comparatorcomparator()返回调用排序集的比......
  • 无涯教程-Java - Set 集合接口函数
    Set集合是不能包含重复元素的集合,Set接口仅包含从Collection继承的方法,并增加了禁止重复元素的限制。下表总结了Set声明的方法-Sr.No.Method&Remark1add()将对象添加到集合中。2clear()从集合中删除所有对象。3contains()如果指定对象是集合中的元素,则返回t......
  • Excel-定义名称 & INDIRECT 函数& 下拉选单设定
    1.定义名称意义:储存格的定义名称,可以将储存格的范围转换成一个容易理解和记忆的名字,比如A1:A5~姓名,将五笔金额设定为一个名称~金额,使我们在设定与维护公式时更加方便,此后再建立公式的时候,不用再用鼠标框选范围,可以直接在括号的后面,输入我们命名的名字。设定:①框选范围-公式-定......
  • 无涯教程-Java - Collection 接口函数
    Collection接口是构建收集框架的基础。它声明了所有集合将拥有的核心方法。下表总结了这些方法。Sr.No.Method&Remark1booleanadd(Objectobj)将obj添加到调用集合中。如果将obj添加到集合中,则返回true。如果obj已经是集合的成员,或者该集合不允许重复,则返回false。2......
  • 无涯教程-Java - Properties 类函数
    Properties是Hashtable的子类。它用于维护值列表,其中键是字符串,并且值也是字符串。属性(Properties)定义以下变量。此变量保存与Properties对象关联的默认属性列表。Propertiesdefaults;以下是properties类提供的构造函数的列表。Sr.No.Constructor&Remark1Properties......
  • Numpy 等函数的读书报告
    importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltplt.rcParams['axes.unicode_minus']=Falseplt.rcParams['font.sans-serif']='SimHei'matplotlib使用里面的函数读取图片,输出图片对应的数组#matplotlib使用里面的函数读取图片,输出图片对应......
  • 无涯教程-Java - Dictionary 类函数
    字典(Dictionary)是一个抽象类,代表一个键/值对,其操作非常类似于Map。下面列出了Dictionary定义的抽象方法-Sr.No.Method&Remark1Enumerationelements()返回字典中包含的值的枚举。2Objectget(Objectkey)返回包含与键关联的值的对象,如果键不在字典中,则返回空对象......
  • 委托、匿名方法和Lambda表达式
    匿名方法和Lambda表达式输出的都是委托类型(也就是一个方法)  lambda表达式的几种形式 ......
  • 无涯教程-Java - Stack 类函数
    堆栈是Vector的子类,它实现了标准的后进先出堆栈。Stack()除了从其父类Vector继承的方法外,Stack还定义了以下方法-Sr.No.Method&Remark1booleanempty()测试此堆栈是否为空。如果堆栈为空,则返回true;如果堆栈包含元素,则返回false。2Objectpeek()返回位于堆栈顶部......