前言:

本来是打算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 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。为什么?就地定义,就地书写,就地使用,方便他人对代码进行研读,同时方便自己使用,何乐而不为?