赞
踩
Lambda有很多种叫法,有Lambda表达式,Lambda函数,匿名函数,本文为了方便表述统一用Lambda表达式叙述。下面是一个Lambda表达式实例。
- #include <algorithm>
- #include <cmath>
-
- void abssort(float* x, unsigned n)
- {
-
- std::sort(x,x+n),
- // Lambda expression begins
- [](float a, float b) {
-
- return (std::abs(a)< std::abs(b));
- }
- // Lambda expression end
- }
在上面的实例中,std::sort 函数第三个参数应该是传递一个 排序规则的函数,但是这个实例中直接将排序函数的 实现:写在了应该传递函数的位置,省去了定义排序函数的过程,对于这种不需要复用且短小的函数,直接传递函数体可以增加代码的可读性。
1:捕获列表:在C++规范中也称为Lambda导入器,捕获列表总是出现在lambda函数的开始处。实际上,[] 是lambda引出符,编译器根据该引出符判断接下来的代码是 lambda函数,捕获列表能够捕捉上下文的变量,以供Lambda函数使用。
2:参数列表:与普通函数的参数列表一致,如果不需要参数传递,则可以连同括号 “()” 一起省略
3:可变规格:mutable修饰符,默认情况下Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可以省略(即使参数为空)
4:异常说明:用于lambda表达式内部函数抛出的异常。
5:返回类型:lambda表达式的函数体返回类型我们可以在不需要返回值得时候可以连同 “->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
说明:lambda表达式的返回类型会自动推导。除非指定了返回类型,否则不必使用关键字。返回类型类似于通常的方法或函数的返回类型部分。但是返回类型必须在参数列表之后,并且必须在返回类型 -> 之前包含类型关键字。如果lambda主体仅包含一个 return语句或者该表达式返回值,那么可以省略Lambda表达式的 return-type 部分,如果Lambda主体包含一个 return语句,则编译器 将从 return表达式的类型中推导出 return类型。否则: 编译器将返回类型推导为 void .
auto x = [ ](int i) {return i ;}
6:lambda函数体:与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
优点
例如:
std::find_if(v.begin(),v.end(),[](int& item) {return item >2} ) ;
缺点:
编译器会把一个Lambda表达式生成一个匿名类的 匿名对象,并在类中重载函数调用运算符,实现 operator()方法。
auto print = [] {cout << " hello world" << endl ; }
编译器会把上述代码翻译为下面代码
- class print_class
- {
-
- public:
- void operator()(void) const {
-
- cout << "hello world" << endl;
- }
-
- };
-
-
- // 用构造的类创建对象,print 此时就是 一个函数对象
- auto print = print_class();
事实上,编译器这么翻译和仿函数基本是一致的。
- #include<iostream>
- #include<string>
-
- using namespace std;
-
- class Functor
- {
- public:
- void operator()(const string& str) const
- {
-
- cout<< str << endl;
- }
-
- }
-
- int main(){
- Functor myFunctor;
- myFunctor("hello");
- return 0;
- }
- #include<iostream>
- #include<string>
- #include<functional>
- #include "lambda_.h"
- using namespace std;
-
- typedef void (*p_nameFunc)(string name);
-
- void use_lambda1() {
- // 1:匿名调用
- [](string name) {
-
- cout << "this is anonymous" << endl;
- cout << "hello" << endl;
- }("jack ma");
-
- // 2:通过auto赋值
- auto fname = [](string name)->string {
- cout << "this is auto" << endl;
- cout << "hello" << endl;
- return "hello world";
- };
- fname("Robin ma");
-
- // 函数指针
- p_nameFunc fname2 = [](string name)
- {
- cout << "this is P_nameFunc" << endl;
- cout << "hello " << name << endl;
- };
- fname2("liu");
-
- // 4:function
- function<void(string)> funcName;
- funcName = [](string name)
- {
- cout << "this is function" << endl;
- cout << "hello " << name << endl;
- };
- funcName("wang");
- }
-
- int main() {
-
- use_lambda1();
- }
- void use_lambda2() {
- int age = 33;
- int score = 100;
- string name = "jack";
- string job = "softengineer";
-
- // 值捕获
- [age, name](string name_)
- {
- cout << "age is: " << age << " name is: " << name << " self-name is: " << name_ << endl;
- // name = "xiaoli"; // error : 表达式必须是可修饰的左值
- // age = 20; // error : 表达式必须是可修饰的左值
- }("vivo");
-
- // 引用捕获
- [&age, &name](string name_)
- {
- cout << "age is: " << age << " name is : " << name << "self-name is: " << name_ << endl;
- name = "xiaoli";
- age = 20;
- }("huawei");
-
- // 全部用值捕获,name用应用捕获
- [=, &name]()
- {
- cout << "age is: " << age << " name is: " << name << " score is: " << score << " job is: " << job << endl;
- name = "cui hua";
- }();
-
- // 全部用引用捕获,只有name 用值捕获
- [&, name]()
- {
- cout << "age is: " << age << " name is: " << name << " score is: " << score << " job is: " << job << endl;
- }();
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。