Lambda Expressions in C++

C++中的Lambda表达式
In Visual C++, a lambda expression—referred to as a lambda—is like an anonymous function that maintains state and can access the variables that are available to the enclosing scope. This article defines what lambdas are, compares them to other programming techniques, describes their advantages, and provides a basic example.

在VC++中,一个lambda表达式——指的是一个lambda(希腊字母)——就像匿名函数一样,保持状态并可访问变量(在作用域(enclosing scope)中有效的)。这篇文章定义了什么叫做Lambda表达式,将它与其他编程技术相比,描述其优越性并提供了基础的例子。

About Lambdas

Many programming languages support the concept of an anonymous function, which is a function that has a body, but doesn't have a name. A lambda is a programming technique that's related to anonymous functions. A lambda implicitly defines a function object class and constructs a function object of that class type. For more information about function objects, see Function Objects.
许多编程语言支持匿名函数的概念,匿名函数是有函数体却没有名称的函数。Lambda正是依赖匿名函数的一种新技术。(隐式的)Lambda表达式定义了一个函数类,并以它(函数类)作为函数对象(类实例化对象,详见百度百科)。预知更多,参考MSDN库有关Function Objects的介绍。

Function Objects vs. Lambdas

When you write code, you probably use function pointers and function objects to solve problems and perform calculations, especially when you use STL algorithms. Function pointers and function objects have advantages and disadvantages—for example, function pointers have minimal syntactic overhead but do not retain state within a scope, and function objects can maintain state but require the syntactic overhead of a class definition.

A lambda combines the benefits of function pointers and function objects and avoids their disadvantages. Like a function objects, a lambda is flexible and can maintain state, but unlike a function object, its compact syntax doesn't require a class definition. By using lambdas, you can write code that's less cumbersome and less prone to errors than the code for an equivalent function object.

The following examples compare the use of a lambda to the use of a function object. The first example uses a lambda to print to the console whether each element in a vector object is even or odd. The second example uses a function object to accomplish the same task.

当你写代码时,你可能会用到函数指针,或函数对象来解决问题或者进行演算,尤其当你用STL algorithms时。函数指针和函数对象(或许可理解为仿函数?)有优缺点——例如,函数指针有最小的句法开销(?)但不能在作用域中保持状态(?),而函数对象能够保持状态却需要一个类的定义(相较而言较大的句法开销)

Lambda表达式融合了他们的优缺点。就像函数对象,Lambda表达式很灵活(于此伴生的是很难理解!!)并可保持状态,不想函数对象,它完整的句法并不需要类的定义。使用lambda表达式可以让你的代码不那么繁琐、并减少出错。
下述几个例子比较了lambda表达式和函数对象。第一个例子使用了lambda表达式在控制台中输出了在Vector容器中的元素的奇偶性。第二个采用了函数对象实现了同样的任务。

Example 1: Using a Lambda

This example uses a lambda that's embedded in the for_each function call to print to the console whether each element in a vector object is even or odd.
这个例子采用了内嵌在for_each函数中的lambda表达式,在控制台中输出vector中元素的奇偶性。
// even_lambda.cpp
// compile with: cl /EHsc /nologo /W4 /MTd
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std; int main()
{
// Create a vector object that contains 10 elements.
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
} // Count the number of even numbers in the vector by
// using the for_each function and a lambda.
int evenCount = 0;
for_each(v.begin(), v.end(), [&evenCount] (int n) {
cout << n; if (n % 2 == 0) {
cout << " is even " << endl;
++evenCount;
} else {
cout << " is odd " << endl;
}
}); // Print the count of even numbers to the console.
cout << "There are " << evenCount
<< " even numbers in the vector." << endl;
}

Output

0 is even
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
There are 5 even numbers in the vector.

Comments

In the example, the third argument to the for_each function is a lambda. The [&evenCount] part specifies the capture clause of the expression, (int n) specifies the parameter list, and remaining part specifies the body of the expression.

在这个例子中,第三个for_each的参数是一个lambda表达式。所谓[&evenCount]部分,明确说明了分句表达式,(int n)明确说明了一个形参(参数?)列表,剩余部分是表达式的主体。

Example 2: Using a Function Object

Sometimes a lambda would be too unwieldy to extend much further than the previous example. The next example uses a function object instead of a lambda, together with the for_each function, to produce the same results as Example 1. Both examples store the count of even numbers in a vector object. To maintain the state of the operation, the FunctorClass class stores the m_evenCount variable by reference as a member variable. To perform the operation, FunctorClass implements the function-call operator, operator(). The Visual C++ compiler generates code that is comparable in size and performance to the lambda code in Example 1. For a basic problem like the one in this article, the simpler lambda design is probably better than the function-object design. However, if you think that the functionality might require significant expansion in the future, then use a function object design so that code maintenance will be easier.

For more information about the operator(), see Function Call (C++). For more information about the for_eachfunction, see for_each.

有时候lambda表达式过于繁杂(扩充功能)。下一个例子采用了函数对象,同样使用for_each。都是数vector元素中偶数个数,为保持操作状态,FunctorClass类保存了m_evenCount变量作为一个成员变量的引用。为实现功能,FunctorClass重载(implement?)了function-call操作符,operator()。VC++编译器产生了与之相当大小和表现得lambda表达式代码(例一)。在这个基本问题中,简易的lambda表达式设计可能比函数对象更好。然而,若你认为functionality(函数性?)可能需要一个明确的扩展,那么就用函数对象写代码,那会简单些。

欲知operator()和for_each,参考Function Call(C++),for_each,在MSDN库内有。
// even_functor.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std; class FunctorClass
{
public:
// The required constructor for this example.
explicit FunctorClass(int& evenCount)
: m_evenCount(evenCount)
{
} // The function-call operator prints whether the number is
// even or odd. If the number is even, this method updates
// the counter.
void operator()(int n) const
{
cout << n; if (n % 2 == 0) {
cout << " is even " << endl;
++m_evenCount;
} else {
cout << " is odd " << endl;
}
} private:
// Default assignment operator to silence warning C4512.
FunctorClass& operator=(const FunctorClass&); int& m_evenCount; // the number of even variables in the vector.
}; int main()
{
// Create a vector object that contains 10 elements.
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
} // Count the number of even numbers in the vector by
// using the for_each function and a function object.
int evenCount = 0;
for_each(v.begin(), v.end(), FunctorClass(evenCount)); // Print the count of even numbers to the console.
cout << "There are " << evenCount
<< " even numbers in the vector." << endl;
}

Summary

Lambdas are a powerful and expressive programming technique. To learn about the parts and properties of a lambda, see Lambda Expression Syntax. To learn how to use lambdas in your programs, see Examples of Lambda Expressions.

Lambda表达式是一个强有力的编程技术。欲知更多,kNLambda Expression Syntax,http://msdn.microsoft.com/en-US/library/dd293603。更多例子在:http://msdn.microsoft.com/en-US/library/dd293599

C++11里面的Lambda表达式的更多相关文章

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

    原文地址:C++中的Lambda表达式 作者:果冻想 一直都在提醒自己,我是搞C++的:但是当C++11出来这么长时间了,我却没有跟着队伍走,发现很对不起自己的身份,也还好,发现自己也有段时间没有写C ...

  2. 【转】C++11新特性——lambda表达式

    C++11的一大亮点就是引入了Lambda表达式.利用Lambda表达式,可以方便的定义和创建匿名函数.对于C++这门语言来说来说,“Lambda表达式”或“匿名函数”这些概念听起来好像很深奥,但很多 ...

  3. C++11新特性 lambda表达式

    C++11 添加了了一个名为lambda表达式的功能,可以用于添加匿名函数 语法: [capture_block](parameter) mutable exception_specification ...

  4. C++ 11 中的 Lambda 表达式的使用

    Lambda在C#中使用得非常频繁,并且可以使代码变得简洁,优雅. 在C++11 中也加入了 Lambda. 它是这个样子的 [] () {}...  是的三种括号开会的节奏~ [] 的作用是表示La ...

  5. 「C++11」Lambda 表达式

    维基百科上面对于 lambda 的引入是如下描述的: 在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find.用户经常希望能够在算法函数调用的附近定义一个临时的述部函数( ...

  6. c++11 新特性之lambda表达式

    写过c#之后,觉得c#里的lambda表达式和delegate配合使用,这样的机制用起来非常爽.c++11也有了lambda表达式,形式上有细小的差异.形式如下: c#:(input paramete ...

  7. C++11 lambda表达式学习

    lambda表达式是函数式编程的基础.咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下.这里只是介绍C++11中的lambda表达式自己的认识.这里有参考文档h ...

  8. C++ 11 Lambda表达式

    C++11的一大亮点就是引入了Lambda表达式.利用Lambda表达式,可以方便的定义和创建匿名函数.对于C++这门语言来说来说,“Lambda表达式”或“匿名函数”这些概念听起来好像很深奥,但很多 ...

  9. C++ 11 Lambda表达式、auto、function、bind、final、override

    接触了cocos2dx 3.0,就必须得看C++ 11了.有分享过帖子:[转帖]漫话C++0x(四) —- function, bind和lambda.其实最后的Lambda没太怎么看懂. 看不懂没关 ...

随机推荐

  1. python scrapy 基础

    scrapy是用python写的一个库,使用它可以方便的抓取网页. 主页地址http://scrapy.org/ 文档 http://doc.scrapy.org/en/latest/index.ht ...

  2. windows下批量杀死进程

    有时候因为病毒或其它原因,启动了一系列的进程,而且有时杀了这个,又多了那个.使用命令taskkill可将这些进程一下子所有杀光: C:\Users\NR>taskkill /F /im fron ...

  3. WHY IE AGAIN? - string.charAt(x) or string[x]?

    近期今天在写一个"删除字符串中反复字符串"的函数,代码例如以下: 开门见山,重点 string.charAt(index) 取代 string[index] function re ...

  4. 纯CSS实现带小角的对话框式下拉菜单

    最近公司首页样式重写,头部下拉菜单改为了带小角的对话框式下拉菜单: 很多人可能会用图片,事实上纯CSS就能够实现: HTML: <!DOCTYPE html> <html lang= ...

  5. iOS横竖屏

    现在开发的APP大部分界面是竖屏的,只有视频播放的界面和webview阅读文字的界面是可以横屏操作的. 那么就进行如下处理: 1.首先确保APP支持横屏旋转 2.我的App里面都是走UINavigat ...

  6. UIView设置少于四个的圆角

    最近的需求中有个label需要设置右下角为圆角,其余三个为直角,一开始用的是重写drawRect,然后用绘图重绘每个角的样子,计算起来还是麻烦 后来发现了下面的方法: UILabel *courseS ...

  7. C#如何获得本地电脑IP

    using System; using System.Collections.Generic; using System.Text; using System.Net;   //需要引用.Net命名空 ...

  8. Effective C++ 第二版 5)new和delete形式 6) 析构函数里的delete

    内存管理 1)正确得到: 正确调用内存分配和释放程序; 2)有效使用: 写特定版本的内存分配和释放程序; C中用mallco分配的内存没有用free返回, 就会产生内存泄漏, C++中则是new和de ...

  9. JVM调优基础

    一.JVM调优基本流程 1.划分应用程序的系统需求优先级 2.选择JVM部署模式:单JVM.多JVM 3.选择JVM运行模式 4.调优应用程序内存使用 5.调优应用程序延迟 6.调优应用程序吞吐量 二 ...

  10. freemarker 的replace功能

    替换字符串 replace ${s?replace(‘ba’, ‘XY’ )} ${s?replace(‘ba’, ‘XY’ , ‘规则参数’)}将s里的所有的ba替换成xy 规则参数包含: i r ...