本文翻译自:What is a lambda expression in C++11?

What is a lambda expression in C++11? 什么是C ++ 11中的lambda表达式? When would I use one? 我什么时候用一个? What class of problem do they solve that wasn't possible prior to their introduction? 在引入之前,他们无法解决什么问题?

A few examples, and use cases would be useful. 一些示例和用例将很有用。


#1楼

参考:https://stackoom.com/question/W09i/什么是C-中的lambda表达式


#2楼

Lambda expressions are typically used to encapsulate algorithms so that they can be passed to another function. Lambda表达式通常用于封装算法,以便可以将它们传递给另一个函数。 However, it is possible to execute a lambda immediately upon definition : 但是, 可以在定义后立即执行lambda

[&](){ ...your code... }(); // immediately executed lambda expression

is functionally equivalent to 在功能上等同于

{ ...your code... } // simple code block

This makes lambda expressions a powerful tool for refactoring complex functions . 这使lambda表达式成为重构复杂函数的强大工具 。 You start by wrapping a code section in a lambda function as shown above. 首先,将代码段包装在lambda函数中,如上所示。 The process of explicit parameterization can then be performed gradually with intermediate testing after each step. 然后,可以在每个步骤之后通过中间测试逐步执行显式参数化的过程。 Once you have the code-block fully parameterized (as demonstrated by the removal of the & ), you can move the code to an external location and make it a normal function. 将代码块完全参数化后(如删除& ),可以将代码移至外部位置并将其设为正常功能。

Similarly, you can use lambda expressions to initialize variables based on the result of an algorithm ... 同样,您可以使用lambda表达式根据算法的结果来初始化变量 ...

int a = []( int b ){ int r=1; while (b>0) r*=b--; return r; }(5); // 5!

As a way of partitioning your program logic , you might even find it useful to pass a lambda expression as an argument to another lambda expression... 作为分区程序逻辑的一种方法 ,您甚至可能发现将lambda表达式作为参数传递给另一个lambda表达式很有用...

[&]( std::function<void()> algorithm ) // wrapper section{...your wrapper code...algorithm();...your wrapper code...}
([&]() // algorithm section{...your algorithm code...});

Lambda expressions also let you create named nested functions , which can be a convenient way of avoiding duplicate logic. Lambda表达式还允许您创建命名的嵌套函数 ,这是避免重复逻辑的便捷方法。 Using named lambdas also tends to be a little easier on the eyes (compared to anonymous inline lambdas) when passing a non-trivial function as a parameter to another function. 当将非平凡的函数作为参数传递给另一个函数时,使用命名的lambda往往也更容易(与匿名内联lambda相比)。 Note: don't forget the semicolon after the closing curly brace. 注意:不要忘了在大括号后加上分号。

auto algorithm = [&]( double x, double m, double b ) -> double{return m*x+b;};int a=algorithm(1,2,3), b=algorithm(4,5,6);

If subsequent profiling reveals significant initialization overhead for the function object, you might choose to rewrite this as a normal function. 如果后续分析显示出该函数对象的大量初始化开销,则可以选择将其重写为普通函数。


#3楼

A lambda function is an anonymous function that you create in-line. Lambda函数是您直接创建的匿名函数。 It can capture variables as some have explained, (eg http://www.stroustrup.com/C++11FAQ.html#lambda ) but there are some limitations. 正如某些人所解释的那样,它可以捕获变量(例如, http : //www.stroustrup.com/C++11FAQ.html#lambda ),但是存在一些限制。 For example, if there's a callback interface like this, 例如,如果有这样的回调接口,

void apply(void (*f)(int)) {f(10);f(20);f(30);
}

you can write a function on the spot to use it like the one passed to apply below: 您可以当场编写一个函数来使用它,就像下面传递的那样:

int col=0;
void output() {apply([](int data) {cout << data << ((++col % 10) ? ' ' : '\n');});
}

But you can't do this: 但是您不能这样做:

void output(int n) {int col=0;apply([&col,n](int data) {cout << data << ((++col % 10) ? ' ' : '\n');});
}

because of limitations in the C++11 standard. 由于C ++ 11标准的局限性。 If you want to use captures, you have to rely on the library and 如果要使用捕获,则必须依赖库

#include <functional>

(or some other STL library like algorithm to get it indirectly) and then work with std::function instead of passing normal functions as parameters like this: (或其他一些类似算法的STL库来间接获取它),然后使用std :: function而不是像这样将普通函数作为参数传递:

#include <functional>
void apply(std::function<void(int)> f) {f(10);f(20);f(30);
}
void output(int width) {int col;apply([width,&col](int data) {cout << data << ((++col % width) ? ' ' : '\n');});
}

#4楼

Answers 答案

Q: What is a lambda expression in C++11? 问:C ++ 11中的lambda表达式是什么?

A: Under the hood, it is the object of an autogenerated class with overloading operator() const . 答:在后台,它是带有重载operator()const的自动生成类的对象。 Such object is called closure and created by compiler. 这种对象称为闭包 ,由编译器创建。 This 'closure' concept is near with the bind concept from C++11. 这个“关闭”概念与C ++ 11的bind概念差不多。 But lambdas typically generate better code. 但是lambda通常会生成更好的代码。 And calls through closures allow full inlining. 通过闭包的调用允许完整的内联。

Q: When would I use one? 问:我什么时候会用一次?

A: To define "simple and small logic" and ask compiler perform generation from previous question. 答:要定义“简单逻辑”,并要求编译器根据上一个问题进行生成。 You give a compiler some expressions which you want to be inside operator(). 您为编译器提供了一些要包含在operator()中的表达式。 All other stuff compiler will generate to you. 所有其他的东西编译器都会为您生成。

Q: What class of problem do they solve that wasn't possible prior to their introduction? 问:在介绍之前,他们无法解决哪种问题?

A: It is some kind of syntax sugar like operators overloading instead of functions for custom add, subrtact operations...But it save more lines of unneeded code to wrap 1-3 lines of real logic to some classes, and etc.! 答:这是一种语法糖,例如运算符重载,而不是自定义添加,子操作的函数……但是它节省了更多的不需要的代码行,可以将1-3行的实际逻辑包装到某些类中,等等! Some engineers think that if the number of lines is smaller then there is a less chance to make errors in it (I'm also think so) 一些工程师认为,如果行数较少,那么出错的机会就更少了(我也这么认为)

Example of usage 使用例

auto x = [=](int arg1){printf("%i", arg1); };
void(*f)(int) = x;
f(1);
x(1);

Extras about lambdas, not covered by question. 有关lambda的其他内容,不在问题范围之内。 Ignore this section if you're not interest 如果您不感兴趣,请忽略此部分

1. Captured values. 1.捕获的值。 What you can to capture 您可以捕获什么

1.1. 1.1。 You can reference to a variable with static storage duration in lambdas. 您可以使用lambdas引用具有静态存储持续时间的变量。 They all are captured. 他们全部被捕获。

1.2. 1.2。 You can use lambda for capture values "by value". 您可以使用lambda来“按值”捕获值。 In such case captured vars will be copied to the function object (closure). 在这种情况下,捕获的变量将被复制到函数对象(关闭)。

[captureVar1,captureVar2](int arg1){}

1.3. 1.3。 You can capture be reference. 您可以参考。 & -- in this context mean reference, not pointers. &-在本文中是指引用,而不是指针。

   [&captureVar1,&captureVar2](int arg1){}

1.4. 1.4。 It exists notation to capture all non-static vars by value, or by reference 它具有表示法,可以按值或按引用捕获所有非静态变量

  [=](int arg1){} // capture all not-static vars by value[&](int arg1){} // capture all not-static vars by reference

1.5. 1.5。 It exists notation to capture all non-static vars by value, or by reference and specify smth. 它存在一种表示法,可以按值或按引用捕获所有非静态var并指定smth。 more. 更多。 Examples: Capture all not-static vars by value, but by reference capture Param2 示例:通过值捕获所有非静态变量,但通过引用捕获Param2

[=,&Param2](int arg1){}

Capture all not-static vars by reference, but by value capture Param2 通过引用捕获所有非静态变量,但通过值捕获Param2

[&,Param2](int arg1){}

2. Return type deduction 2.返回类型扣除

2.1. 2.1。 Lambda return type can be deduced if lambda is one expression. 如果lambda是一个表达式,则可以推断出lambda返回类型。 Or you can explicitly specify it. 或者您可以显式指定它。

[=](int arg1)->trailing_return_type{return trailing_return_type();}

If lambda has more then one expression, then return type must be specified via trailing return type. 如果lambda具有多个表达式,则必须通过尾随返回类型指定返回类型。 Also, similar syntax can be applied to auto functions and member-functions 同样,类似的语法可以应用于自动功能和成员功能

3. Captured values. 3.捕获的值。 What you can not capture 您无法捕获的内容

3.1. 3.1。 You can capture only local vars, not member variable of the object. 您只能捕获本地var,而不能捕获对象的成员变量。

4. Сonversions 4.转换

4.1 !! 4.1 !! Lambda is not a function pointer and it is not an anonymous function, but capture-less lambdas can be implicitly converted to a function pointer. Lambda不是函数指针,也不是匿名函数,但是可以将无捕获的 Lambda隐式转换为函数指针。

ps ps

  1. More about lambda grammar information can be found in Working draft for Programming Language C++ #337, 2012-01-16, 5.1.2. 有关lambda语法信息的更多信息,请参见《 C ++编程语言》工作草案#337、2012-01-16、5.1.2。 Lambda Expressions, p.88 Lambda表达式,第88页

  2. In C++14 the extra feature which has named as "init capture" have been added. 在C ++ 14中,添加了名为“初始捕获”的额外功能。 It allow to perform arbitarily declaration of closure data members: 它允许任意执行闭包数据成员的声明:

     auto toFloat = [](int value) { return float(value);}; auto interpolate = [min = toFloat(0), max = toFloat(255)](int value)->float { return (value - min) / (max - min);}; 

#5楼

One problem it solves: Code simpler than lambda for a call in constructor that uses an output parameter function for initializing a const member 它解决的一个问题是: 在构造函数中使用输出参数函数初始化const成员的调用的代码比lambda更简单

You can initialize a const member of your class, with a call to a function that sets its value by giving back its output as an output parameter. 您可以通过调用返回其输出作为输出参数来设置其值的函数来初始化类的const成员。


#6楼

Well, one practical use I've found out is reducing boiler plate code. 好吧,我发现的一种实际用途是减少样板代码。 For example: 例如:

void process_z_vec(vector<int>& vec)
{auto print_2d = [](const vector<int>& board, int bsize){for(int i = 0; i<bsize; i++){for(int j=0; j<bsize; j++){cout << board[bsize*i+j] << " ";}cout << "\n";}};// Do sth with the vec.print_2d(vec,x_size);// Do sth else with the vec.print_2d(vec,y_size);//...
}

Without lambda, you may need to do something for different bsize cases. 如果没有lambda,则可能需要为不同的bsize情况做一些事情。 Of course you could create a function but what if you want to limit the usage within the scope of the soul user function? 当然,您可以创建一个函数,但是如果您想在灵魂用户函数的范围内限制使用该怎么办? the nature of lambda fulfills this requirement and I use it for that case. lambda的性质满足了此要求,在这种情况下,我会使用它。

什么是C ++ 11中的lambda表达式?相关推荐

  1. C++ 11中的Lambda表达式

    1. 概述 C++ 11 中的 Lambda 表达式用于定义匿名类(anonymous class).创建匿名类对象,以简化编程工作.编译器为该类添加操作符重载函数void operator()(ar ...

  2. C++11中的Lambda表达式

    本文地址:http://www.cnblogs.com/archimedes/p/c11-lambda.html,转载请注明源地址. "Lambda 表达式"(lambda exp ...

  3. 探索Java语言与JVM中的Lambda表达式

    2019独角兽企业重金招聘Python工程师标准>>> 转载来源:http://www.admin10000.com/document/1291.html Lambda表达式是自Ja ...

  4. C++中的Lambda表达式详解

    函数对象与Lambdas 你编写代码时,尤其是使用 STL 算法时,可能会使用函数指针和函数对象来解决问题和执行计算.函数指针和函数对象各有利弊.例如,函数指针具有最低的语法开销,但不保持范围内的状态 ...

  5. lambda qt 参数 槽函数_C++中的lambda表达式用法

    #include <QCoreApplication> #include <QDebug> int main(int argc, char *argv[]) {QCoreApp ...

  6. Qt5中使用lambda表达式

    c11新特性中加入了lambda表达式,所以Qt 也支持 需在.pro文件中加入 CONFIG += c++11例子: 1 QString program = "C:/Windows/Sys ...

  7. C++11新特性——λ(lambda)表达式详解

    C++11新特性--λ(lambda)表达式 C++11中引入了λ表达式,它可以用来定义一个内联(inline)的函数,作为一个本地的对象或者一个参数.有了λ表达式,我们可以很方便的使用stl标准库. ...

  8. Python中的Lambda表达式

    Lambda表达式 (Lambda Expressions) Lambda Expressions are ideally used when we need to do something simp ...

  9. android studio lambda插件,在Android Studio中使用Lambda表达式(retrolambda)

    在Android Studio中使用Lambda表达式 要在Android Studio中使用Lambda表达式,需要借助一个gradle插件来完成. A gradle plugin for gett ...

最新文章

  1. SGML与HTML、XML
  2. ECEF rectangular coordinate system(ECEF直角坐标系)
  3. boost::gil::detail::is_channel_integral用法的测试程序
  4. Linux 线程与互斥锁的使用
  5. C++(13)--函数的进阶:内联、传递引用、参数默认值、重载、函数模板
  6. python methodtype_Python的实例定属性和方法或类绑定方法
  7. 统计数据:Google排名高的是什么样的页面?
  8. 一张图了解互联网产品盈利模式
  9. php根据某个字段去重,php二维数组根据某个字段去重
  10. 人工智能被拒绝,语音识别做不到给电视直播加字幕?
  11. iis启动服务时提示在本地计算机 无法启动iis admin服务,无法启动IIS Express Web服务器...
  12. 怎样学习数据结构? 伯克利神课CS61B 总结感悟,学习指南和避坑建议
  13. 超好用的截屏标注软件Snipaste
  14. 昨天面试题目--软件--SQL--后感
  15. 慎用chrome密码记住功能
  16. X-Y非线性关系或U型倒U型曲线的检验
  17. MIT TR 35揭晓:阿里巴巴王刚、吴翰清等六位华人当选,Ian Goodfellow上榜
  18. Hive分析函数之SUM,AVG,MIN和MAX OVER(PARTITION BY xxx order by xxx,用于求一段时间内截至到每天的累计访问次数、平均访问次数、最小访问次数、最大访问次
  19. docker安装_使用docker在带有SSL的Nginx反向代理后面部署Quarkus或任何基于Java的微服务...
  20. linux启动mysql1820_Linux下安装mysql

热门文章

  1. 自己动手实现OpenGL!
  2. 算法------买卖股票的最佳时机
  3. 你有没有想过你的上级为什么让你干这件事情,他想干什么
  4. Android之ActivityManagerService详解(APP启动过程)
  5. UITableViewHeader 动态调整高度
  6. windows 如何配置 Go 环境(Zip archive 方式)?
  7. hihoCoder week3 KMP算法
  8. taskset -pc PID 查看线程占用cpu核
  9. 部署node.js的开发环境
  10. va_start和va_end使用详解