【C++】【lambda】lambda函数介绍和个人理解(2)——lambda与仿函数

前言:


本来是打算11月末的时候写这篇文章,结果一直拖拖拖拖拖啊啊啊啊啊事多啊事多!OK这是对lambda的分析的第二篇,第三篇准备给大家带来一些“语法甜点”,不过实在是不知道什么时候能够写完=。=到时候再说

导航:

lambda函数介绍和个人理解(1)——初识lambda

lambda函数介绍和个人理解(2)——lambda与仿函数

lambda函数介绍和个人理解(3)——lambda的语法甜点

正文:

好点的编程语言一般都有好的库支持,C++也不例外。C++语言在标准程序库STL中向用户提供了一些基本的数据结构及一些基本的算法等。在C++11之前,我们在使用STL算法时,通常会用到一个特殊的对象,一般来说,我们称之为函数对象,或者仿函数(functor)。仿函数简单地说,就是重定义了成员函数operator()的一种自定义类型对象。这样的对象有个特点,就是其使用在代码层面感觉跟函数的使用并无二样,但究其本质却并非函数。这里有一个简单的仿函数的例子(其实仿函数并特性不是C++11的特性,因为当前不支持C++11的在线评测系统POJ目前可以编译仿函数,这个例子就成功的AC了POJ的测试题目POJ1000)。


/****
*@PoloShen
*Title: lambda 03
*Addition: Also worked and ACed POJ1000
*/
#include <iostream>
using namespace std;

class _functor{
public:
int operator()(int x, int y){return x+y; }
};
int main(){
int a, b;
_functor Plus;
cin >> a >> b;
cout << Plus(a,b) << endl;
return 0;
}
//编译选项:: g++ -std=c++11 lambda03.cpp

在示例中,class
_functor的operator()被重载,因此,在调用该函数的时候,我们看到跟函数调用一样的形式,只不过在这里的Plus不再是函数名称,而是对象名称。

当然,既然仿函数是披着函数的对象,那么就可以像处理一般的对象一样,可以对对象的部分成员进行初始化。注意,其实在这里,因为这个仿函数是一个对象,那么换句话说,你就可以初始化出来很多原理相似但是结果几乎是完全不同的仿函数示例。比如说下面的那个例子。


/****
*@PoloShen
*Title: lambda 04
*/
#include <iostream>
using namespace std;

class Tax{
/*说明
作用:计算税收
计算公式:
( 收入 - 纳税线 ) * 税率
*/
public:
Tax(): rate(0), base(0){}
Tax(double r, double b): rate(r), base(b){}
double operator()(double money){return (money - base) * rate;}
private:
double rate;
double base;
};
int main(){
Tax high(0.40, 30000);
Tax middle(0.25, 20000);
cout << "tax over 3w: " << high(37500) << endl;
cout << "tax over 2w: " << middle(27500) <<endl;
return 0;
}
//编译选项:: g++ -std=c++11 lambda04.cpp

不过,如果我们把这些乱七八糟的皮毛剥去,其实lambda函数的定义和仿函数的构造是极其相似的。回到最开始的例子,我们把自定义类型中的声明和其中对象的定义,至少从代码的角度上去看,基本上而这毫无差异。那么我们所抛弃的那些声明和定义究竟是lambda函数中的哪个部分呢?不卖关子了,先看一份代码。


/****
*@PoloShen
*Title: lambda 05
*/
#include <iostream>
using namespace std;

class AirportPrice{
/*说明
作用:计算机场反税
计算公式:
金额 * ( 1 - 税率)
提示:
传入的税率是百分数。
*/
public:
AirportPrice(): m_fDutyFreeRate(0){}
AirportPrice(double r): m_fDutyFreeRate(r){}
double operator()(double money){
return money * (1 - m_fDutyFreeRate/100);
}
private:
double m_fDutyFreeRate;
};
int main(){
double tax_rate = 5.5;
AirportPrice test1(tax_rate);
auto test2 = [tax_rate](double money)->double{
return money * (1 - tax_rate/100);
};

cout << "By functor: " << test1(3699) << endl;
cout << "By lambda : " << test2(3699) << endl;
return 0;
}
//编译选项:: g++ -std=c++11 lambda05.cpp

这份代码是一个计算机场反税的例子。test1和test2分别是用仿函数和lambda两种方式来计算扣税后产品价格。请留意下二者的tax_rate的“捕捉”方式。lambda函数通过书写时的捕捉列表来捕捉tax_rate变量。仿函数是通过tax_rate初始化类,并且构造出名为test1的一个AirportPrice类实例。而在其他方面,参数的传递上,二者保持一致,一模一样。在目标值的返回上也和正常的普通函数毫无差别。因而,实际上,除了语法和实际的书写,在某种意义上,我们可以认为lambda和仿函数是一个“产物”。换句话说,他们两个都可以捕捉一些变量作为初始状态,并接受参数进行运算。

开头我提到了STL算法中的函数对象,通过上文的描述,我们可以认为函数对象里的两个元素:lambda和仿函数是等价的,我们可以人工的——当然,只要你愿意写多余的代码就行——把lambda和仿函数进行互相转化。当然,如果编译器已经完美支持C++11的话,完全可以把所有的仿函数啊函数指针神马的妥妥的换成lambda。为什么?就地定义,就地书写,就地使用,方便他人对代码进行研读,同时方便自己使用,何乐而不为?

时间: 2024-10-13 18:23:22

【C++】【lambda】lambda函数介绍和个人理解(2)——lambda与仿函数的相关文章

【C++】【lambda】lambda函数介绍和个人理解(3)——lambda的语法甜点

导航: lambda函数介绍和个人理解(1)--初识lambda lambda函数介绍和个人理解(2)--lambda与仿函数 lambda函数介绍和个人理解(3)--lambda的语法甜点 其实,与其说这是一篇介绍lambda语法甜点的文章,不如说是一篇教大家使用lambda函数的一篇文章.当然不可避免的会用到一些有趣的实验.文章略长,大家耐心耐心看吧!当然,这也是本人写的关于lambda函数的最后一篇博文了,如果大家有其他更好的想法或者更深入的理解,请联系我~ 本文大概讲这些内容:基础使用,

【C++】【lambda】lambda函数介绍和个人理解(1)——初识lambda

导航: lambda函数介绍和个人理解(1)--初识lambda lambda函数介绍和个人理解(2)--lambda与仿函数 lambda函数介绍和个人理解(3)--lambda的语法甜点 什么是lambda函数? 其实,lambda函数我个人更愿意称为lambda运算(lambdacalculus),它是用来表示一种匿名函数.这个严格意义上属于"函数式编程"(Functional Programming)的范畴.当然还是先解释下函数式编程的概念的好.按照当时冯·诺依曼机器的基本计算

【C++】lambda函数介绍和个人理解

一般数据类型的别名 众所周知,在C++中,有一种不同于地址引用的值引用类型,也就是这种定义. int a = 10; cout << a << endl;//:10 int& d = a;//d为a的别名 cout << d << endl;//:10 a++; cout << a << endl;//:11 d++; cout << a << endl;//:12 cout << d &l

lambda 匿名函数,map,filter,reduce,zip,介绍

sum_1=lambda x,y:x+yprint(sum_1(1,2)) l=[1,2,3,4]print(list(map(lambda x:x*4,l)))#map()将函数func应用于序列seq中的所有元素.# 在Python3之前,map()返回一个列表,# 列表中的每个元素都是将列表或元组"seq"中的相应元素传入函数func返回的结果#使用map就相当于使用了一个for循环def my_map(func,seq): result=[] for i in seq: res

Python的lambda匿名函数

lambda函数也叫匿名函数,即,函数没有具体的名称.先来看一个最简单例子: def f(x):return x**2print f(4) Python中使用lambda的话,写成这样 g = lambda x : x**2print g(4) lambda表达式在很多编程语言都有对应的实现.比如C#: var g = x => x**2Console.WriteLine(g(4)) 那么,lambda表达式有什么用处呢?很多人提出了质疑,lambda和普通的函数相比,就是省去了函数名称而已,同

c++11 lambda(匿名函数)

#include <iostream> #include <functional> using namespace std::placeholders; //lambda即匿名函数 int main() { int a = 10; //当return所有的返回都是一个类型就不需要指定返回值的类型,因为编译器会自动推断 //也可以指定返回值类型形式:[]()->int{return 1}; //格式:[captures] (params) -> ret {Statment

python学习之lambda匿名函数

1 Python支持运行时使用“lambda”建立匿名函数(anonymous functions that are not bound to a name). python "lambda"和functional programming语言有区别,但是他非常强大经常拿来和诸如filter(),map(),reduce()等经典概念结合. 以下示例普通函数和匿名函数: 1 In [113]: def normalFun (x): return x**2 2 3 In [114]: pr

python: lambda 匿名函数

lambda 匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便. 在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数: >>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])) [1, 4, 9, 16, 25, 36, 49, 64, 81] 通过对比可以看出,匿名函数lambda x: x *

20180720 (lambda匿名函数,sorded()排序函数,filter()筛选函数,map()映射函数,递归,二分函数)

一.lambda匿名函数           (一行搞定一个函数,但是不能完成复杂的函数操作) 语法:函数名 = lambda 参数 : 返回值 注意: 1.函数的参数可以有多个,多个参数之间用逗号隔开 2.匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据 3.返回值和正常的函数一样,可以是任意数据类型 例如:普通函数 def func(n) return n*n print(func(6))               ======>36 例如:lambda a = lambda x