C++中lambda的实质是什么?

我们知道lambda表达式的行为很像是是一个匿名函数,我们常常在标准算法中使用lambda表达式。比如需要打印一个向量,可能会这样写:

vector<int> v(10, 10);

std::for_each(v.begin(), v.end(), [](int n){
    cout << n << " ";
});

使用了for_each算法针对 v 中的每一个元素使用lambda表达式,并且成功的达到了目的。

但是看看下面这个方式也可以完成任务:

std::for_each(v.begin(), v.end(), print_int);

这里的print_int 是什么呢?多数人都会知道它是一个形如void print_int(int)的函数,没错,但是他还可以是另外一类截然不同的类型,也就是说它并不是一个函数。

在学习类的运算符重载的时候,很多人可能会忽略掉()的重载,也就是括号的重载。我们知道对类的括号进行重载就能想函数一样使用类对象。举例如下:

class Print{
    void operator()(int n){
        cout << n << " ";
    }
};

Print print_int;  //声明类对象
print_int(3);     //使用了()运算符

这样我们将3打印出来了。所以上面for_each语句中的print_int也可以是一个类对象。说这些的目的只是为了引出下面的话题,那就是lambda表达式的本质是什么?

其实在C++中,lambda表达式都被编译器翻译成了一个未命名的类的一个未命名对象。上面的lambda表达式,就被翻译成了形如Print类的一个未命名类,而在for_each中,声明了一个未命名的对象,然后使用其括号运输符来完成 v 中各个元素的处理。

我们知道,lambda表达式前面的 [] 是捕获列表,而捕获方式有通过引用捕获和通过值捕获。当通过值引用的时候,编译器在创建类的时候,会将这个值作为类成员变量,而在声明未命名对象的时候,将这个类成员初始化为所引用的变量当前的值。

当通过引用的方式捕获时,编译器不会将其存储为类成员。下面通过一个例子来说明以上内容。

int value = 100;
auto it = find_if(v.begin(),v.end(),[value](const int n){
    return n<value;
});
cout<<*it;

上面这段代码是为了找到 v 中小于 100 的第一个数,这里我将长度最大长度按值传递给lambda表达式。编译器为之可能产生下面这个类:

class XXX{
public:
    XXX(int x):value(x){}  //这里的x就是捕获列表中的变量 --- [value]
    bool operator()(const int n)const{  //这里与lambda的参数,返回值,函数体一致
        return n<value;
    }
private:
    int value;
};

之后,我们可以这样做:

int value = 100;

XXX xx(value);
auto it = find_if(v.begin(), v.end(), xx);
cout<<*it;

毫无疑问,这里find_if对v中每一个元素调用了xx.operator(int n),通过返回值得到了指向第一个小于value的值的迭代器。

其实你还可以这样使用XXX类:

auto it = find_if(v.begin(), v.end(), XXX(100));

现在你或许对lambda表达式有有了一些认识,所以不妨自己定义一个这样的类来测试一下,是否真的如我这里所说。

时间: 2024-08-06 11:56:53

C++中lambda的实质是什么?的相关文章

c++中调用函数实质

(m_pListener->*m_pfnSelector)(this); m_pListener是class的实例 m_pFnSelector是存的函数的指针 这句可能要稍微解释下,其实也挺好懂的.首先前面这个括号就是对应的函数,后面的this就是参数,这个满足对函数指针的定义,即void (CCObject::*)(CCObject*); 因为CCMenuItem基类是CCObject,那其实调用的场景(CScene)基类也一样.然后就是m_pListener->*m_pfnSelector

python中lambda

lambda_expr ::= "lambda" [parameter_list]: expression python中lambda可以理解为一个匿名函数,它的要求是函数的运算部分只能是一个表达式,参数部分可以有多个参数

python中lambda的另类使用

Lambda挺强大,有兴趣的人看下关于lambda的理论,就清楚邱奇编码的实现了. 网上的都只是讲的千篇一律的匿名函数的简单用法,很没趣. 那些建议取消python中lambda的同志,知道lambda可以这么用么. 带if/else: ( lambda x, y: x if x < y else y )( 1, 2 ) 科里化: ( lambda x: ( lambda y: ( lambda z: x + y + z )( 1 ) )( 2 ) )( 3 ) 递归: func = lambd

Java8 Collections.sort()及Arrays.sort()中Lambda表达式及增强版Comparator的使用

摘要:本文主要介绍Java8 中Arrays.sort()及Collections.sort()中Lambda表达式及增强版Comparator的使用. 不废话直接上代码 import com.google.common.collect.Lists; import org.junit.Assert; import org.junit.Test; import java.util.Arrays; import java.util.Collections; import java.util.Comp

实例讲解C++中lambda表达式

测试环境 windows 7  vs2013 C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作.例如GPU编程中常用到. 一个最简单的lamada表达式程序 #include <functional> #include <iostream> using namespace std; int main() {     function<void(void)>  fun = [](){cout << "hello lamb

Scheme中lambda表达式与函数指针小例

SICP/Chapter2/Exercise-2.4 Lambda表达式语法 (lambda kw-formals body) 题目描述 用过程性表示方式重写序对的cons.car.cdr Scheme代码 (define (cons-24 x y) (lambda (m) (m x y))) (define (car-24 z) (z (lambda (p q) p))) 这段代码只有4行,但是逻辑关系并不好理解. 原因在于函数式语言的自顶向下实现方式不符合一般的逻辑习惯. lambda以类似

Python中lambda用法

lambda只是一个表达式,函数体比def简单很多. lambda的主体是一个表达式,而不是一个代码块.仅仅能在lambda表达式中封装有限的逻辑进去. lambda表达式是起到一个函数速写的作用.允许在代码内嵌入一个函数的定义. 如下例子: 定义了一个lambda表达式,求三个数的和. 再看一个例子: 用lambda表达式求n的阶乘. ------------------------------ lambda表达式也可以用在def函数中. 看例子: 这里定义了一个action函数,返回了一个l

java 8 中lambda表达式学习

转自 http://blog.csdn.net/renfufei/article/details/24600507 http://www.jdon.com/idea/java/10-example-of-lambda-expressions-in-java8.html Lambda表达式的语法基本语法:(parameters) -> expression或(parameters) ->{ statements; } 下面是Java lambda表达式的简单例子: // 1. 不需要参数,返回值

python中lambda表达式应用

对于简单的函数,也存在一种简便的表示方式,即:lambda表达式 #普通函数1 def func(a): 2 return a+1 3 print 'test1_func0:',func(1000)4#lambda表达式 5 func0 = lambda a:a+1 6 print 'test2_func0:',func0(1000) 上面这种方法,都实现了将1000+1的结果打印出来这个功能,但是用下面 lambda存在意义就是对简单函数的简洁表示. 说道lambda,这里再赠送一些可以给la