Lambda特性

来源:互联网 发布:毕业论文检测软件 编辑:程序博客网 时间:2024/06/08 16:07

lambda是c++11的一个非常好的新特性,当需要添加一个临时的函数时,使用lambda非常方便。

lambda的写法如下:

[函数外部对象参数](函数参数) -> 返回值类型{ 函数体 }

1.[ ]中的函数外部对象参数,允许在函数体内直接调用函数外部的参数。

2.( )中的函数参数,同正常函数的参数一样,是每次函数调用传入的变量。

3.->后面跟着的是函数的返回值类型。

4. {}中可以编写逻辑,并使用[]和()中传入的参数。

定义在lambda函数相同作用域的参数引用也可以被使用,这种参数集合一般被称为闭包,[ ]中可以填写下面几种类型的参数,将定义lambda函数的作用域内的变量传入函数体中。

  1.[ ]没用任何参数,这种情况下不传入外部参数。

2.[a, &b]传入变量a的值以及变量b的引用。

3.[&]以引用方式传入所有变量。

4.[=]以传值的方式传入所有变量,但值不可被修改。

5.[&, a]除了a以值的方式传入,其余的所有变量以引用方式传入。

6.[=, &a]除了a以引用的方式传入,其余的所有变量以值的方式传入。

下面编写一个测试用例,当在lambda函数中使用了=传入的参数,且对引用参数或外部参数进行赋值操作后,会产生意想不到的结果,而在使用&时需要注意的是引用对象的生命周期。

#include <iostream>void main(){int a, b, c;auto fun0 = [&]()->void{ a = 1; b = 2; c = 3; };auto fun1 = []()->int {return 2 * 3; };auto fun2 = [=, &a, &b]()->void {++a, b += c + a; };auto fun3 = [=]()->int {return a + c; };fun0();std::cout << a << "\t" << b << "\t" << c << std::endl;c = fun1();std::cout << a << "\t" << b << "\t" << c << std::endl;fun2();std::cout << a << "\t" << b << "\t" << c << std::endl;b = fun3();std::cout << a << "\t" << b << "\t" << c << std::endl;}
运行结果如下:

因为默认情况下,Lambda函数总是一个const函数,用mutable可以取消其常量性。按照规定,一个const的成员函数是不能在函数体内修改非静态成员变量的值。所以有=传入时不要对传入的参数进行赋值操作。

当lambda被定义在类的成员函数中时,lambda可以调用该类的private函数;当lambda调用该类的成员函数时,操作成员变量或其他成员函数时,需要将this传入,=和&会传入this。

使用std::function可以存储lambda函数。例如,可以用function<void()>来存放fun(),function<int()>来存放fun1,带参数的函数可以在()内输入参数类型,在使用function时要包含头文件functional。

#include <functional>std::function<void()> f1 = fun0;std::function<int()> f2 = fun1;
function还可以用于存放普通函数,静态函数和类的共有成员函数,前两者和lambda的用法一样,直接将函数名赋值给function对象即可(无法识别重载的函数),但类的成员函数需要使用bind来绑定。
classA *obj = new classA;std::function<void(int)> f3 = std::bind(&classA::memberFun1, obj, std::placeholders::_1);std::function<void(int, char)> f4 = std::bind(&classA::memberFun2, obj, std::placeholders::_1, std::placeholders::_2);delete obj;
使用bind绑定成员函数和对象指针,使用placeholders占位符来表示函数的参数数量,依次为1~N。

原创粉丝点击